From f76c5efe633f0ce27ab45fa8ada6115608eec82f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Dec 2023 19:05:24 +0000 Subject: [PATCH 01/65] Bump roborazzi from 1.6.0 to 1.7.0 Bumps `roborazzi` from 1.6.0 to 1.7.0. Updates `io.github.takahirom.roborazzi:roborazzi` from 1.6.0 to 1.7.0 - [Release notes](https://github.com/takahirom/roborazzi/releases) - [Commits](https://github.com/takahirom/roborazzi/compare/1.6.0...1.7.0) Updates `io.github.takahirom.roborazzi` from 1.6.0 to 1.7.0 - [Release notes](https://github.com/takahirom/roborazzi/releases) - [Commits](https://github.com/takahirom/roborazzi/compare/1.6.0...1.7.0) --- updated-dependencies: - dependency-name: io.github.takahirom.roborazzi:roborazzi dependency-type: direct:production update-type: version-update:semver-minor - dependency-name: io.github.takahirom.roborazzi dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a4ff74adc..e7b61f249 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -54,7 +54,7 @@ protobufPlugin = "0.9.4" retrofit = "2.9.0" retrofitKotlinxSerializationJson = "1.0.0" robolectric = "4.11.1" -roborazzi = "1.6.0" +roborazzi = "1.7.0" room = "2.6.1" secrets = "2.0.1" truth = "1.1.5" From 1875020fab8db07088ba11501c925ab594df40bb Mon Sep 17 00:00:00 2001 From: Arash Ebrahimzade <68777571+aarash709@users.noreply.github.com> Date: Wed, 10 Jan 2024 13:21:26 +0330 Subject: [PATCH 02/65] Updated screenshot tests link --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6f13f5de2..be1270b16 100644 --- a/README.md +++ b/README.md @@ -122,9 +122,9 @@ tests against _all_ build variants which is both unecessary and will result in f A screenshot test takes a screenshot of a screen or a UI component within the app, and compares it with a previously recorded screenshot which is known to be rendered correctly. -For example, Now in Android has [screenshot tests](https://github.com/android/nowinandroid/blob/main/app/src/testDemoDebug/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt) +For example, Now in Android has [screenshot tests](https://github.com/android/nowinandroid/blob/main/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt) to verify that the navigation is displayed correctly on different screen sizes -([known correct screenshots](https://github.com/android/nowinandroid/tree/main/app/src/testDemoDebug/screenshots)). +([known correct screenshots](https://github.com/android/nowinandroid/tree/main/app/src/testDemo/screenshots)). Now In Android uses [Roborazzi](https://github.com/takahirom/roborazzi) to run screenshot tests of certain screens and UI components. When working with screenshot tests the following gradle tasks are useful: From c307446e69fcf16c13bb839d512ef8484e726f50 Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Sat, 27 Jan 2024 10:05:21 +0000 Subject: [PATCH 03/65] Move `androidx.compose.ui:ui-tooling` dependency to convention plugin --- .../com/google/samples/apps/nowinandroid/AndroidCompose.kt | 1 + core/designsystem/build.gradle.kts | 3 --- gradle/libs.versions.toml | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt index 039987cac..6e08c2658 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt @@ -41,6 +41,7 @@ internal fun Project.configureAndroidCompose( val bom = libs.findLibrary("androidx-compose-bom").get() add("implementation", platform(bom)) add("androidTestImplementation", platform(bom)) + add("debugImplementation", libs.findLibrary("androidx-compose-ui-tooling").get()) } testOptions { diff --git a/core/designsystem/build.gradle.kts b/core/designsystem/build.gradle.kts index d68117d06..75e59f255 100644 --- a/core/designsystem/build.gradle.kts +++ b/core/designsystem/build.gradle.kts @@ -35,11 +35,8 @@ dependencies { api(libs.androidx.compose.material.iconsExtended) api(libs.androidx.compose.material3) api(libs.androidx.compose.runtime) - api(libs.androidx.compose.ui.tooling.preview) api(libs.androidx.compose.ui.util) - debugApi(libs.androidx.compose.ui.tooling) - implementation(libs.coil.kt.compose) testImplementation(libs.androidx.compose.ui.test) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 795510bce..ab11f9279 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -75,7 +75,6 @@ androidx-compose-runtime = { group = "androidx.compose.runtime", name = "runtime androidx-compose-ui-test = { group = "androidx.compose.ui", name = "ui-test-junit4" } androidx-compose-ui-testManifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } -androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } androidx-compose-ui-util = { group = "androidx.compose.ui", name = "ui-util" } androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "androidxCore" } androidx-core-splashscreen = { group = "androidx.core", name = "core-splashscreen", version.ref = "androidxCoreSplashscreen" } From f2bd71c87b9acbd6f41dd18e9ddcbcfbea9829b1 Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Sat, 27 Jan 2024 10:25:24 +0000 Subject: [PATCH 04/65] Keep `androidx.compose.ui:ui-tooling-preview` on all buildTypes --- .../com/google/samples/apps/nowinandroid/AndroidCompose.kt | 1 + gradle/libs.versions.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt index 6e08c2658..a4b3d0501 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt @@ -41,6 +41,7 @@ internal fun Project.configureAndroidCompose( val bom = libs.findLibrary("androidx-compose-bom").get() add("implementation", platform(bom)) add("androidTestImplementation", platform(bom)) + add("implementation", libs.findLibrary("androidx-compose-ui-tooling-preview").get()) add("debugImplementation", libs.findLibrary("androidx-compose-ui-tooling").get()) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ab11f9279..795510bce 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -75,6 +75,7 @@ androidx-compose-runtime = { group = "androidx.compose.runtime", name = "runtime androidx-compose-ui-test = { group = "androidx.compose.ui", name = "ui-test-junit4" } androidx-compose-ui-testManifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } +androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } androidx-compose-ui-util = { group = "androidx.compose.ui", name = "ui-util" } androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "androidxCore" } androidx-core-splashscreen = { group = "androidx.core", name = "core-splashscreen", version.ref = "androidxCoreSplashscreen" } From c6c2b03e40abb1ae01a06d4eaca82a74b4f2555a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jan 2024 08:18:10 +0000 Subject: [PATCH 05/65] Bump gradle/gradle-build-action from 2 to 3 Bumps [gradle/gradle-build-action](https://github.com/gradle/gradle-build-action) from 2 to 3. - [Release notes](https://github.com/gradle/gradle-build-action/releases) - [Commits](https://github.com/gradle/gradle-build-action/compare/v2...v3) --- updated-dependencies: - dependency-name: gradle/gradle-build-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/Build.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Build.yaml b/.github/workflows/Build.yaml index 9bd84abc0..76b85a5a2 100644 --- a/.github/workflows/Build.yaml +++ b/.github/workflows/Build.yaml @@ -37,7 +37,7 @@ jobs: java-version: 17 - name: Setup Gradle - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@v3 - name: Check build-logic run: ./gradlew check -p build-logic @@ -144,7 +144,7 @@ jobs: java-version: 17 - name: Setup Gradle - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@v3 - name: Build projects before running emulator run: ./gradlew packageDemoDebug packageDemoDebugAndroidTest From 40c72de60afbb99bfb4c6fafc4571118a0492555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mlynari=C4=8D?= Date: Mon, 29 Jan 2024 15:59:12 +0100 Subject: [PATCH 06/65] Add Composition Tracing Change-Id: I3ad60930de2fab71a700a0c2df3f0a1f566cafd8 --- app/build.gradle.kts | 1 + gradle/libs.versions.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 38166f7ff..aded864ee 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -104,6 +104,7 @@ dependencies { implementation(libs.androidx.core.splashscreen) implementation(libs.androidx.tracing.ktx) implementation(libs.androidx.lifecycle.runtimeCompose) + implementation(libs.androidx.compose.runtime.tracing) implementation(libs.androidx.compose.material3.windowSizeClass) implementation(libs.androidx.navigation.compose) implementation(libs.androidx.profileinstaller) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 795510bce..1ef4cc225 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -72,6 +72,7 @@ androidx-compose-material-iconsExtended = { group = "androidx.compose.material", androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" } androidx-compose-material3-windowSizeClass = { group = "androidx.compose.material3", name = "material3-window-size-class" } androidx-compose-runtime = { group = "androidx.compose.runtime", name = "runtime" } +androidx-compose-runtime-tracing = { group = "androidx.compose.runtime", name = "runtime-tracing", version.ref = "androidxComposeRuntimeTracing" } androidx-compose-ui-test = { group = "androidx.compose.ui", name = "ui-test-junit4" } androidx-compose-ui-testManifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } From c432f740547f64187313d515a592deb0a2c25b08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mlynari=C4=8D?= Date: Mon, 29 Jan 2024 22:58:47 +0100 Subject: [PATCH 07/65] Add TimeZoneMonitor to prevent multiple TimeZoneBroadcastReceivers This way, we can save ~1ms per composed item on screen. Change-Id: Ib9ada3cea53304fca4fb2b36c48c175845bc683d --- .../apps/nowinandroid/ui/NavigationUiTest.kt | 86 +++++------------ .../apps/nowinandroid/ui/NiaAppStateTest.kt | 31 ++++++ .../samples/apps/nowinandroid/MainActivity.kt | 27 ++++-- .../samples/apps/nowinandroid/ui/NiaApp.kt | 31 +++--- .../apps/nowinandroid/ui/NiaAppState.kt | 28 ++++-- .../ui/NiaAppScreenSizesScreenshotTests.kt | 8 +- .../foryou/ScrollForYouFeedBenchmark.kt | 4 + .../apps/nowinandroid/AndroidCompose.kt | 10 +- compose_compiler_config.conf | 6 ++ .../data/test/DefaultZoneIdTimeZoneMonitor.kt | 27 ++++++ .../core/data/test/TestDataModule.kt | 4 + .../nowinandroid/core/data/di/DataModule.kt | 5 + .../core/data/util/TimeZoneMonitor.kt | 94 +++++++++++++++++++ .../core/testing/util/TestTimeZoneMonitor.kt | 41 ++++++++ .../nowinandroid/core/ui/LocalTimeZone.kt | 26 +++++ .../nowinandroid/core/ui/NewsResourceCard.kt | 29 +----- .../core/ui/TimeZoneBroadcastReceiver.kt | 50 ---------- gradle/libs.versions.toml | 6 +- 18 files changed, 337 insertions(+), 176 deletions(-) create mode 100644 compose_compiler_config.conf create mode 100644 core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/DefaultZoneIdTimeZoneMonitor.kt create mode 100644 core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt create mode 100644 core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/TestTimeZoneMonitor.kt create mode 100644 core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/LocalTimeZone.kt delete mode 100644 core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/TimeZoneBroadcastReceiver.kt diff --git a/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NavigationUiTest.kt b/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NavigationUiTest.kt index d92390918..5d2e12b5c 100644 --- a/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NavigationUiTest.kt +++ b/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NavigationUiTest.kt @@ -19,14 +19,17 @@ package com.google.samples.apps.nowinandroid.ui import androidx.compose.foundation.layout.BoxWithConstraints import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi import androidx.compose.material3.windowsizeclass.WindowSizeClass +import androidx.compose.runtime.Composable import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.onNodeWithTag +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.dp import com.google.accompanist.testharness.TestHarness import com.google.samples.apps.nowinandroid.core.data.repository.CompositeUserNewsResourceRepository import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor +import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor import com.google.samples.apps.nowinandroid.core.rules.GrantPostNotificationsPermissionRule import com.google.samples.apps.nowinandroid.core.testing.repository.TestNewsRepository import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository @@ -81,6 +84,9 @@ class NavigationUiTest { @Inject lateinit var networkMonitor: NetworkMonitor + @Inject + lateinit var timeZoneMonitor: TimeZoneMonitor + @Before fun setup() { hiltRule.inject() @@ -91,13 +97,7 @@ class NavigationUiTest { composeTestRule.setContent { TestHarness(size = DpSize(400.dp, 400.dp)) { BoxWithConstraints { - NiaApp( - windowSizeClass = WindowSizeClass.calculateFromSize( - DpSize(maxWidth, maxHeight), - ), - networkMonitor = networkMonitor, - userNewsResourceRepository = userNewsResourceRepository, - ) + NiaApp(fakeAppState(maxWidth, maxHeight)) } } } @@ -111,13 +111,7 @@ class NavigationUiTest { composeTestRule.setContent { TestHarness(size = DpSize(610.dp, 400.dp)) { BoxWithConstraints { - NiaApp( - windowSizeClass = WindowSizeClass.calculateFromSize( - DpSize(maxWidth, maxHeight), - ), - networkMonitor = networkMonitor, - userNewsResourceRepository = userNewsResourceRepository, - ) + NiaApp(fakeAppState(maxWidth, maxHeight)) } } } @@ -131,13 +125,7 @@ class NavigationUiTest { composeTestRule.setContent { TestHarness(size = DpSize(900.dp, 400.dp)) { BoxWithConstraints { - NiaApp( - windowSizeClass = WindowSizeClass.calculateFromSize( - DpSize(maxWidth, maxHeight), - ), - networkMonitor = networkMonitor, - userNewsResourceRepository = userNewsResourceRepository, - ) + NiaApp(fakeAppState(maxWidth, maxHeight)) } } } @@ -151,13 +139,7 @@ class NavigationUiTest { composeTestRule.setContent { TestHarness(size = DpSize(400.dp, 500.dp)) { BoxWithConstraints { - NiaApp( - windowSizeClass = WindowSizeClass.calculateFromSize( - DpSize(maxWidth, maxHeight), - ), - networkMonitor = networkMonitor, - userNewsResourceRepository = userNewsResourceRepository, - ) + NiaApp(fakeAppState(maxWidth, maxHeight)) } } } @@ -171,13 +153,7 @@ class NavigationUiTest { composeTestRule.setContent { TestHarness(size = DpSize(610.dp, 500.dp)) { BoxWithConstraints { - NiaApp( - windowSizeClass = WindowSizeClass.calculateFromSize( - DpSize(maxWidth, maxHeight), - ), - networkMonitor = networkMonitor, - userNewsResourceRepository = userNewsResourceRepository, - ) + NiaApp(fakeAppState(maxWidth, maxHeight)) } } } @@ -191,13 +167,7 @@ class NavigationUiTest { composeTestRule.setContent { TestHarness(size = DpSize(900.dp, 500.dp)) { BoxWithConstraints { - NiaApp( - windowSizeClass = WindowSizeClass.calculateFromSize( - DpSize(maxWidth, maxHeight), - ), - networkMonitor = networkMonitor, - userNewsResourceRepository = userNewsResourceRepository, - ) + NiaApp(fakeAppState(maxWidth, maxHeight)) } } } @@ -211,13 +181,7 @@ class NavigationUiTest { composeTestRule.setContent { TestHarness(size = DpSize(400.dp, 1000.dp)) { BoxWithConstraints { - NiaApp( - windowSizeClass = WindowSizeClass.calculateFromSize( - DpSize(maxWidth, maxHeight), - ), - networkMonitor = networkMonitor, - userNewsResourceRepository = userNewsResourceRepository, - ) + NiaApp(fakeAppState(maxWidth, maxHeight)) } } } @@ -231,13 +195,7 @@ class NavigationUiTest { composeTestRule.setContent { TestHarness(size = DpSize(610.dp, 1000.dp)) { BoxWithConstraints { - NiaApp( - windowSizeClass = WindowSizeClass.calculateFromSize( - DpSize(maxWidth, maxHeight), - ), - networkMonitor = networkMonitor, - userNewsResourceRepository = userNewsResourceRepository, - ) + NiaApp(fakeAppState(maxWidth, maxHeight)) } } } @@ -251,13 +209,7 @@ class NavigationUiTest { composeTestRule.setContent { TestHarness(size = DpSize(900.dp, 1000.dp)) { BoxWithConstraints { - NiaApp( - windowSizeClass = WindowSizeClass.calculateFromSize( - DpSize(maxWidth, maxHeight), - ), - networkMonitor = networkMonitor, - userNewsResourceRepository = userNewsResourceRepository, - ) + NiaApp(fakeAppState(maxWidth, maxHeight)) } } } @@ -265,4 +217,12 @@ class NavigationUiTest { composeTestRule.onNodeWithTag("NiaNavRail").assertIsDisplayed() composeTestRule.onNodeWithTag("NiaBottomBar").assertDoesNotExist() } + + @Composable + private fun fakeAppState(maxWidth: Dp, maxHeight: Dp) = rememberNiaAppState( + windowSizeClass = WindowSizeClass.calculateFromSize(DpSize(maxWidth, maxHeight)), + networkMonitor = networkMonitor, + userNewsResourceRepository = userNewsResourceRepository, + timeZoneMonitor = timeZoneMonitor, + ) } diff --git a/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt b/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt index 1560a74eb..18afc6a09 100644 --- a/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt +++ b/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt @@ -34,12 +34,14 @@ import com.google.samples.apps.nowinandroid.core.data.repository.CompositeUserNe import com.google.samples.apps.nowinandroid.core.testing.repository.TestNewsRepository import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository import com.google.samples.apps.nowinandroid.core.testing.util.TestNetworkMonitor +import com.google.samples.apps.nowinandroid.core.testing.util.TestTimeZoneMonitor import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest import org.junit.Rule import org.junit.Test +import java.time.ZoneId import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertTrue @@ -59,6 +61,8 @@ class NiaAppStateTest { // Create the test dependencies. private val networkMonitor = TestNetworkMonitor() + private val timeZoneMonitor = TestTimeZoneMonitor() + private val userNewsResourceRepository = CompositeUserNewsResourceRepository(TestNewsRepository(), TestUserDataRepository()) @@ -78,6 +82,7 @@ class NiaAppStateTest { windowSizeClass = getCompactWindowClass(), networkMonitor = networkMonitor, userNewsResourceRepository = userNewsResourceRepository, + timeZoneMonitor = timeZoneMonitor, ) } @@ -100,6 +105,7 @@ class NiaAppStateTest { windowSizeClass = getCompactWindowClass(), networkMonitor = networkMonitor, userNewsResourceRepository = userNewsResourceRepository, + timeZoneMonitor = timeZoneMonitor, ) } @@ -118,6 +124,7 @@ class NiaAppStateTest { windowSizeClass = getCompactWindowClass(), networkMonitor = networkMonitor, userNewsResourceRepository = userNewsResourceRepository, + timeZoneMonitor = timeZoneMonitor, ) } @@ -134,6 +141,7 @@ class NiaAppStateTest { windowSizeClass = WindowSizeClass.calculateFromSize(DpSize(800.dp, 800.dp)), networkMonitor = networkMonitor, userNewsResourceRepository = userNewsResourceRepository, + timeZoneMonitor = timeZoneMonitor, ) } @@ -150,6 +158,7 @@ class NiaAppStateTest { windowSizeClass = WindowSizeClass.calculateFromSize(DpSize(900.dp, 1200.dp)), networkMonitor = networkMonitor, userNewsResourceRepository = userNewsResourceRepository, + timeZoneMonitor = timeZoneMonitor, ) } @@ -166,6 +175,7 @@ class NiaAppStateTest { windowSizeClass = WindowSizeClass.calculateFromSize(DpSize(900.dp, 1200.dp)), networkMonitor = networkMonitor, userNewsResourceRepository = userNewsResourceRepository, + timeZoneMonitor = timeZoneMonitor, ) } @@ -177,6 +187,27 @@ class NiaAppStateTest { ) } + @Test + fun niaAppState_differentTZ_withTimeZoneMonitorChange() = runTest(UnconfinedTestDispatcher()) { + composeTestRule.setContent { + state = NiaAppState( + navController = NavHostController(LocalContext.current), + coroutineScope = backgroundScope, + windowSizeClass = getCompactWindowClass(), + networkMonitor = networkMonitor, + userNewsResourceRepository = userNewsResourceRepository, + timeZoneMonitor = timeZoneMonitor, + ) + } + val changedTz = ZoneId.of("Europe/Prague") + backgroundScope.launch { state.currentTimeZone.collect() } + timeZoneMonitor.setTimeZone(changedTz) + assertEquals( + changedTz, + state.currentTimeZone.value, + ) + } + private fun getCompactWindowClass() = WindowSizeClass.calculateFromSize(DpSize(500.dp, 300.dp)) } diff --git a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt index 6ce134ef4..779b6edbe 100644 --- a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt +++ b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt @@ -28,6 +28,7 @@ import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue @@ -42,10 +43,13 @@ import com.google.samples.apps.nowinandroid.core.analytics.AnalyticsHelper import com.google.samples.apps.nowinandroid.core.analytics.LocalAnalyticsHelper import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourceRepository import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor +import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand +import com.google.samples.apps.nowinandroid.core.ui.LocalTimeZone import com.google.samples.apps.nowinandroid.ui.NiaApp +import com.google.samples.apps.nowinandroid.ui.rememberNiaAppState import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.onEach @@ -67,6 +71,9 @@ class MainActivity : ComponentActivity() { @Inject lateinit var networkMonitor: NetworkMonitor + @Inject + lateinit var timeZoneMonitor: TimeZoneMonitor + @Inject lateinit var analyticsHelper: AnalyticsHelper @@ -126,17 +133,25 @@ class MainActivity : ComponentActivity() { onDispose {} } - CompositionLocalProvider(LocalAnalyticsHelper provides analyticsHelper) { + val appState = rememberNiaAppState( + windowSizeClass = calculateWindowSizeClass(this), + networkMonitor = networkMonitor, + userNewsResourceRepository = userNewsResourceRepository, + timeZoneMonitor = timeZoneMonitor, + ) + + val currentTimeZone by appState.currentTimeZone.collectAsState() + + CompositionLocalProvider( + LocalAnalyticsHelper provides analyticsHelper, + LocalTimeZone provides currentTimeZone, + ) { NiaTheme( darkTheme = darkTheme, androidTheme = shouldUseAndroidTheme(uiState), disableDynamicTheming = shouldDisableDynamicTheming(uiState), ) { - NiaApp( - networkMonitor = networkMonitor, - windowSizeClass = calculateWindowSizeClass(this), - userNewsResourceRepository = userNewsResourceRepository, - ) + NiaApp(appState) } } } diff --git a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt index 2beda99ea..b2eabe2ed 100644 --- a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt +++ b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt @@ -39,7 +39,6 @@ import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarResult.ActionPerformed import androidx.compose.material3.Text import androidx.compose.material3.TopAppBarDefaults -import androidx.compose.material3.windowsizeclass.WindowSizeClass import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -62,8 +61,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavDestination import androidx.navigation.NavDestination.Companion.hierarchy import com.google.samples.apps.nowinandroid.R -import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourceRepository -import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaBackground import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaGradientBackground import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavigationBar @@ -85,16 +82,7 @@ import com.google.samples.apps.nowinandroid.feature.settings.R as settingsR ExperimentalComposeUiApi::class, ) @Composable -fun NiaApp( - windowSizeClass: WindowSizeClass, - networkMonitor: NetworkMonitor, - userNewsResourceRepository: UserNewsResourceRepository, - appState: NiaAppState = rememberNiaAppState( - networkMonitor = networkMonitor, - windowSizeClass = windowSizeClass, - userNewsResourceRepository = userNewsResourceRepository, - ), -) { +fun NiaApp(appState: NiaAppState) { val shouldShowGradientBackground = appState.currentTopLevelDestination == TopLevelDestination.FOR_YOU var showSettingsDialog by rememberSaveable { mutableStateOf(false) } @@ -195,13 +183,16 @@ fun NiaApp( ) } - NiaNavHost(appState = appState, onShowSnackbar = { message, action -> - snackbarHostState.showSnackbar( - message = message, - actionLabel = action, - duration = Short, - ) == ActionPerformed - }) + NiaNavHost( + appState = appState, + onShowSnackbar = { message, action -> + snackbarHostState.showSnackbar( + message = message, + actionLabel = action, + duration = Short, + ) == ActionPerformed + }, + ) } // TODO: We may want to add padding or spacer when the snackbar is shown so that diff --git a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt index 7b66efb06..ffd0c16ec 100644 --- a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt +++ b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt @@ -32,6 +32,7 @@ import androidx.navigation.navOptions import androidx.tracing.trace import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourceRepository import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor +import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor import com.google.samples.apps.nowinandroid.core.ui.TrackDisposableJank import com.google.samples.apps.nowinandroid.feature.bookmarks.navigation.BOOKMARKS_ROUTE import com.google.samples.apps.nowinandroid.feature.bookmarks.navigation.navigateToBookmarks @@ -50,12 +51,14 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn +import java.time.ZoneId @Composable fun rememberNiaAppState( windowSizeClass: WindowSizeClass, networkMonitor: NetworkMonitor, userNewsResourceRepository: UserNewsResourceRepository, + timeZoneMonitor: TimeZoneMonitor, coroutineScope: CoroutineScope = rememberCoroutineScope(), navController: NavHostController = rememberNavController(), ): NiaAppState { @@ -66,13 +69,15 @@ fun rememberNiaAppState( windowSizeClass, networkMonitor, userNewsResourceRepository, + timeZoneMonitor, ) { NiaAppState( - navController, - coroutineScope, - windowSizeClass, - networkMonitor, - userNewsResourceRepository, + navController = navController, + coroutineScope = coroutineScope, + windowSizeClass = windowSizeClass, + networkMonitor = networkMonitor, + userNewsResourceRepository = userNewsResourceRepository, + timeZoneMonitor = timeZoneMonitor, ) } } @@ -80,10 +85,11 @@ fun rememberNiaAppState( @Stable class NiaAppState( val navController: NavHostController, - val coroutineScope: CoroutineScope, + coroutineScope: CoroutineScope, val windowSizeClass: WindowSizeClass, networkMonitor: NetworkMonitor, userNewsResourceRepository: UserNewsResourceRepository, + private val timeZoneMonitor: TimeZoneMonitor, ) { val currentDestination: NavDestination? @Composable get() = navController @@ -127,12 +133,20 @@ class NiaAppState( FOR_YOU.takeIf { forYouNewsResources.any { !it.hasBeenViewed } }, BOOKMARKS.takeIf { bookmarkedNewsResources.any { !it.hasBeenViewed } }, ) - }.stateIn( + } + .stateIn( coroutineScope, SharingStarted.WhileSubscribed(5_000), initialValue = emptySet(), ) + val currentTimeZone = timeZoneMonitor.currentZoneId + .stateIn( + coroutineScope, + SharingStarted.WhileSubscribed(5_000), + ZoneId.systemDefault(), + ) + /** * UI logic for navigating to a top level destination in the app. Top level destinations have * only one copy of the destination of the back stack, and save and restore state whenever you diff --git a/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt b/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt index dcbc1e5c0..f3514b02f 100644 --- a/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt +++ b/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt @@ -37,6 +37,7 @@ import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepositor import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourceRepository import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor +import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions import com.google.samples.apps.nowinandroid.uitesthiltmanifest.HiltComponentActivity import dagger.hilt.android.testing.BindValue @@ -93,6 +94,9 @@ class NiaAppScreenSizesScreenshotTests { @Inject lateinit var networkMonitor: NetworkMonitor + @Inject + lateinit var timeZoneMonitor: TimeZoneMonitor + @Inject lateinit var userDataRepository: UserDataRepository @@ -140,13 +144,15 @@ class NiaAppScreenSizesScreenshotTests { ) { TestHarness(size = DpSize(width, height)) { BoxWithConstraints { - NiaApp( + val fakeAppState = rememberNiaAppState( windowSizeClass = WindowSizeClass.calculateFromSize( DpSize(maxWidth, maxHeight), ), networkMonitor = networkMonitor, userNewsResourceRepository = userNewsResourceRepository, + timeZoneMonitor = timeZoneMonitor, ) + NiaApp(fakeAppState) } } } diff --git a/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/foryou/ScrollForYouFeedBenchmark.kt b/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/foryou/ScrollForYouFeedBenchmark.kt index 6d0091cd4..24a50dd79 100644 --- a/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/foryou/ScrollForYouFeedBenchmark.kt +++ b/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/foryou/ScrollForYouFeedBenchmark.kt @@ -38,6 +38,9 @@ class ScrollForYouFeedBenchmark { @Test fun scrollFeedCompilationBaselineProfile() = scrollFeed(CompilationMode.Partial()) + @Test + fun scrollFeedCompilationFull() = scrollFeed(CompilationMode.Full()) + private fun scrollFeed(compilationMode: CompilationMode) = benchmarkRule.measureRepeated( packageName = PACKAGE_NAME, metrics = listOf(FrameTimingMetric()), @@ -55,3 +58,4 @@ class ScrollForYouFeedBenchmark { forYouScrollFeedDownUp() } } + diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt index 039987cac..72d37db1b 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/AndroidCompose.kt @@ -53,7 +53,8 @@ internal fun Project.configureAndroidCompose( tasks.withType().configureEach { kotlinOptions { - freeCompilerArgs = freeCompilerArgs + buildComposeMetricsParameters() + freeCompilerArgs += buildComposeMetricsParameters() + freeCompilerArgs += stabilityConfiguration() } } } @@ -68,7 +69,7 @@ private fun Project.buildComposeMetricsParameters(): List { val metricsFolder = buildDir.resolve("compose-metrics").resolve(relativePath) metricParameters.add("-P") metricParameters.add( - "plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" + metricsFolder.absolutePath + "plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" + metricsFolder.absolutePath, ) } @@ -83,3 +84,8 @@ private fun Project.buildComposeMetricsParameters(): List { } return metricParameters.toList() } + +private fun Project.stabilityConfiguration() = listOf( + "-P", + "plugin:androidx.compose.compiler.plugins.kotlin:stabilityConfigurationPath=${project.rootDir.absolutePath}/compose_compiler_config.conf", +) diff --git a/compose_compiler_config.conf b/compose_compiler_config.conf new file mode 100644 index 000000000..2341256f4 --- /dev/null +++ b/compose_compiler_config.conf @@ -0,0 +1,6 @@ +// This file contains classes (with possible wildcards) that the Compose Compiler will treat as stable. +// It allows us to define classes that our not part of our codebase without wrapping them in a stable class. +// For more information, check https://developer.android.com/jetpack/compose/performance/stability/fix#configuration-file + +java.time.ZoneId +java.time.ZoneOffset diff --git a/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/DefaultZoneIdTimeZoneMonitor.kt b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/DefaultZoneIdTimeZoneMonitor.kt new file mode 100644 index 000000000..ee8fe97a3 --- /dev/null +++ b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/DefaultZoneIdTimeZoneMonitor.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2024 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. + */ + +package com.google.samples.apps.nowinandroid.core.data.test + +import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf +import java.time.ZoneId +import javax.inject.Inject + +class DefaultZoneIdTimeZoneMonitor @Inject constructor() : TimeZoneMonitor { + override val currentZoneId: Flow = flowOf(ZoneId.of("Europe/Warsaw")) +} diff --git a/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/TestDataModule.kt b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/TestDataModule.kt index 2ec2bcf9c..5bd2b8a43 100644 --- a/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/TestDataModule.kt +++ b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/TestDataModule.kt @@ -28,6 +28,7 @@ import com.google.samples.apps.nowinandroid.core.data.repository.fake.FakeSearch import com.google.samples.apps.nowinandroid.core.data.repository.fake.FakeTopicsRepository import com.google.samples.apps.nowinandroid.core.data.repository.fake.FakeUserDataRepository import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor +import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor import dagger.Binds import dagger.Module import dagger.hilt.components.SingletonComponent @@ -68,4 +69,7 @@ interface TestDataModule { fun bindsNetworkMonitor( networkMonitor: AlwaysOnlineNetworkMonitor, ): NetworkMonitor + + @Binds + fun binds(impl: DefaultZoneIdTimeZoneMonitor): TimeZoneMonitor } diff --git a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/di/DataModule.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/di/DataModule.kt index e135d7f58..fa4bde8b8 100644 --- a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/di/DataModule.kt +++ b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/di/DataModule.kt @@ -28,6 +28,8 @@ import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepositor import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository import com.google.samples.apps.nowinandroid.core.data.util.ConnectivityManagerNetworkMonitor import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor +import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneBroadcastMonitor +import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor import dagger.Binds import dagger.Module import dagger.hilt.InstallIn @@ -66,4 +68,7 @@ abstract class DataModule { internal abstract fun bindsNetworkMonitor( networkMonitor: ConnectivityManagerNetworkMonitor, ): NetworkMonitor + + @Binds + internal abstract fun binds(impl: TimeZoneBroadcastMonitor): TimeZoneMonitor } diff --git a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt new file mode 100644 index 000000000..33b37934a --- /dev/null +++ b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt @@ -0,0 +1,94 @@ +/* + * Copyright 2024 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. + */ + +package com.google.samples.apps.nowinandroid.core.data.util + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.os.Build.VERSION +import android.os.Build.VERSION_CODES +import androidx.core.os.trace +import com.google.samples.apps.nowinandroid.core.network.Dispatcher +import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO +import com.google.samples.apps.nowinandroid.core.network.di.ApplicationScope +import dagger.hilt.android.qualifiers.ApplicationContext +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.shareIn +import java.time.ZoneId +import javax.inject.Inject +import javax.inject.Singleton + +/** + * Utility for reporting current timezone the device has set. + * It always emits at least once with default setting and then for each TZ change. + */ +interface TimeZoneMonitor { + val currentZoneId: Flow +} + +@Singleton +internal class TimeZoneBroadcastMonitor @Inject constructor( + @ApplicationContext private val context: Context, + @ApplicationScope appScope: CoroutineScope, + @Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher, +) : TimeZoneMonitor { + + override val currentZoneId: SharedFlow = + callbackFlow { + // Send the default time zone first. + trySend(ZoneId.systemDefault()) + + // Registers BroadcastReceiver for the TimeZone changes + val receiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + if (intent.action != Intent.ACTION_TIMEZONE_CHANGED) return + + val zoneIdFromIntent = if (VERSION.SDK_INT < VERSION_CODES.R) { + null + } else { + // Starting Android R we also get the new TimeZone. + intent.getStringExtra(Intent.EXTRA_TIMEZONE)?.let { zoneId -> + // We need to convert it from java.util.Timezone to java.time.ZoneId + ZoneId.of(zoneId, ZoneId.SHORT_IDS) + } + } + + // If there isn't a zoneId in the intent, fallback to the systemDefault, which should also reflect the change + trySend(zoneIdFromIntent ?: ZoneId.systemDefault()) + } + } + + trace("TimeZoneBroadcastReceiver.register") { + context.registerReceiver(receiver, IntentFilter(Intent.ACTION_TIMEZONE_CHANGED)) + } + + awaitClose { + context.unregisterReceiver(receiver) + } + } + .flowOn(ioDispatcher) + // Sharing the callback to prevent multiple BroadcastReceivers being registered + .shareIn(appScope, SharingStarted.WhileSubscribed(5_000), 1) +} diff --git a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/TestTimeZoneMonitor.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/TestTimeZoneMonitor.kt new file mode 100644 index 000000000..8eb438fb1 --- /dev/null +++ b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/TestTimeZoneMonitor.kt @@ -0,0 +1,41 @@ +/* + * 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. + */ + +package com.google.samples.apps.nowinandroid.core.testing.util + +import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import java.time.ZoneId + +class TestTimeZoneMonitor : TimeZoneMonitor { + + private val timeZoneFlow = MutableStateFlow(defaultTimeZone) + + override val currentZoneId: Flow = timeZoneFlow + + /** + * A test-only API to set the from tests. + */ + fun setTimeZone(zoneId: ZoneId) { + timeZoneFlow.value = zoneId + } + + companion object { + val defaultTimeZone: ZoneId = ZoneId.of("Europe/Warsaw") + } +} + diff --git a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/LocalTimeZone.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/LocalTimeZone.kt new file mode 100644 index 000000000..cda5040bd --- /dev/null +++ b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/LocalTimeZone.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2024 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. + */ + +package com.google.samples.apps.nowinandroid.core.ui + +import androidx.compose.runtime.compositionLocalOf +import java.time.ZoneId + +/** + * TimeZone that can be provided with the TimeZoneMonitor. + * This way, it's not needed to pass every single composable the time zone to show in UI. + */ +val LocalTimeZone = compositionLocalOf { ZoneId.systemDefault() } diff --git a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index 9eca6b141..c922d9687 100644 --- a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -40,7 +40,6 @@ import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -49,7 +48,6 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalInspectionMode import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -71,7 +69,6 @@ import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource import kotlinx.datetime.Instant import kotlinx.datetime.toJavaInstant -import java.time.ZoneId import java.time.format.DateTimeFormatter import java.time.format.FormatStyle import java.util.Locale @@ -244,27 +241,11 @@ fun NotificationDot( } @Composable -fun dateFormatted(publishDate: Instant): String { - var zoneId by remember { mutableStateOf(ZoneId.systemDefault()) } - - val context = LocalContext.current - - DisposableEffect(context) { - val receiver = TimeZoneBroadcastReceiver( - onTimeZoneChanged = { zoneId = ZoneId.systemDefault() }, - ) - receiver.register(context) - onDispose { - receiver.unregister(context) - } - } - - return DateTimeFormatter - .ofLocalizedDate(FormatStyle.MEDIUM) - .withLocale(Locale.getDefault()) - .withZone(zoneId) - .format(publishDate.toJavaInstant()) -} +fun dateFormatted(publishDate: Instant): String = DateTimeFormatter + .ofLocalizedDate(FormatStyle.MEDIUM) + .withLocale(Locale.getDefault()) + .withZone(LocalTimeZone.current) + .format(publishDate.toJavaInstant()) @Composable fun NewsResourceMetaData( diff --git a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/TimeZoneBroadcastReceiver.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/TimeZoneBroadcastReceiver.kt deleted file mode 100644 index f7ae813c4..000000000 --- a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/TimeZoneBroadcastReceiver.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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. - */ - -package com.google.samples.apps.nowinandroid.core.ui - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import android.content.IntentFilter - -class TimeZoneBroadcastReceiver( - val onTimeZoneChanged: () -> Unit, -) : BroadcastReceiver() { - private var registered = false - - override fun onReceive(context: Context, intent: Intent) { - if (intent.action == Intent.ACTION_TIMEZONE_CHANGED) { - onTimeZoneChanged() - } - } - - fun register(context: Context) { - if (!registered) { - val filter = IntentFilter() - filter.addAction(Intent.ACTION_TIMEZONE_CHANGED) - context.registerReceiver(this, filter) - registered = true - } - } - - fun unregister(context: Context) { - if (registered) { - context.unregisterReceiver(this) - registered = false - } - } -} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1ef4cc225..5bcdaf41c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,7 +8,7 @@ androidxActivity = "1.8.0" androidxAppCompat = "1.6.1" androidxBrowser = "1.6.0" androidxComposeBom = "2023.10.01" -androidxComposeCompiler = "1.5.7" +androidxComposeCompiler = "1.5.8" androidxComposeRuntimeTracing = "1.0.0-beta01" androidxCore = "1.12.0" androidxCoreSplashscreen = "1.0.1" @@ -40,11 +40,11 @@ hilt = "2.50" hiltExt = "1.1.0" jacoco = "0.8.7" junit4 = "4.13.2" -kotlin = "1.9.21" +kotlin = "1.9.22" kotlinxCoroutines = "1.7.3" kotlinxDatetime = "0.5.0" kotlinxSerializationJson = "1.6.0" -ksp = "1.9.21-1.0.16" +ksp = "1.9.22-1.0.16" okhttp = "4.12.0" protobuf = "3.24.4" protobufPlugin = "0.9.4" From fa16457b5e8c8f6e49d196d35c26592494400dba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mlynari=C4=8D?= Date: Tue, 30 Jan 2024 13:34:01 +0100 Subject: [PATCH 08/65] Fix spotless Change-Id: I6583fa9ed7c1563f6164653be9bbaf7904ec0215 --- .../apps/nowinandroid/foryou/ScrollForYouFeedBenchmark.kt | 1 - .../apps/nowinandroid/core/testing/util/TestTimeZoneMonitor.kt | 1 - 2 files changed, 2 deletions(-) diff --git a/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/foryou/ScrollForYouFeedBenchmark.kt b/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/foryou/ScrollForYouFeedBenchmark.kt index 24a50dd79..c74d79307 100644 --- a/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/foryou/ScrollForYouFeedBenchmark.kt +++ b/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/foryou/ScrollForYouFeedBenchmark.kt @@ -58,4 +58,3 @@ class ScrollForYouFeedBenchmark { forYouScrollFeedDownUp() } } - diff --git a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/TestTimeZoneMonitor.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/TestTimeZoneMonitor.kt index 8eb438fb1..1d7f21543 100644 --- a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/TestTimeZoneMonitor.kt +++ b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/TestTimeZoneMonitor.kt @@ -38,4 +38,3 @@ class TestTimeZoneMonitor : TimeZoneMonitor { val defaultTimeZone: ZoneId = ZoneId.of("Europe/Warsaw") } } - From 64a325ae6c510b0a1a12a5573eefbca4ca84cc8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mlynari=C4=8D?= Date: Tue, 30 Jan 2024 20:26:17 +0100 Subject: [PATCH 09/65] Conflate TimeZoneMonitor emissions Co-authored-by: Alex Vanyo --- .../samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt index 33b37934a..04b2ef352 100644 --- a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt +++ b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt @@ -88,6 +88,7 @@ internal class TimeZoneBroadcastMonitor @Inject constructor( context.unregisterReceiver(receiver) } } + .conflate() .flowOn(ioDispatcher) // Sharing the callback to prevent multiple BroadcastReceivers being registered .shareIn(appScope, SharingStarted.WhileSubscribed(5_000), 1) From e19d43531784fa4b2147fd5404cb0a86f506564b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mlynari=C4=8D?= Date: Tue, 30 Jan 2024 20:29:12 +0100 Subject: [PATCH 10/65] Rename LocalTimeZone -> LocalZoneId + collects with lifecycle Change-Id: I429c563765a489965d0a1741e36c98a30e5d0ef3 --- .../com/google/samples/apps/nowinandroid/MainActivity.kt | 8 ++++---- .../core/ui/{LocalTimeZone.kt => LocalZoneId.kt} | 4 ++-- .../samples/apps/nowinandroid/core/ui/NewsResourceCard.kt | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) rename core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/{LocalTimeZone.kt => LocalZoneId.kt} (87%) diff --git a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt index 779b6edbe..0bf45f125 100644 --- a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt +++ b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt @@ -28,12 +28,12 @@ import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.DisposableEffect -import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.lifecycle.Lifecycle +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import androidx.metrics.performance.JankStats @@ -47,7 +47,7 @@ import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand -import com.google.samples.apps.nowinandroid.core.ui.LocalTimeZone +import com.google.samples.apps.nowinandroid.core.ui.LocalZoneId import com.google.samples.apps.nowinandroid.ui.NiaApp import com.google.samples.apps.nowinandroid.ui.rememberNiaAppState import dagger.hilt.android.AndroidEntryPoint @@ -140,11 +140,11 @@ class MainActivity : ComponentActivity() { timeZoneMonitor = timeZoneMonitor, ) - val currentTimeZone by appState.currentTimeZone.collectAsState() + val currentZoneId by appState.currentTimeZone.collectAsStateWithLifecycle() CompositionLocalProvider( LocalAnalyticsHelper provides analyticsHelper, - LocalTimeZone provides currentTimeZone, + LocalZoneId provides currentZoneId, ) { NiaTheme( darkTheme = darkTheme, diff --git a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/LocalTimeZone.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/LocalZoneId.kt similarity index 87% rename from core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/LocalTimeZone.kt rename to core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/LocalZoneId.kt index cda5040bd..54aa7931d 100644 --- a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/LocalTimeZone.kt +++ b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/LocalZoneId.kt @@ -20,7 +20,7 @@ import androidx.compose.runtime.compositionLocalOf import java.time.ZoneId /** - * TimeZone that can be provided with the TimeZoneMonitor. + * ZoneId that can be provided with the TimeZoneMonitor. * This way, it's not needed to pass every single composable the time zone to show in UI. */ -val LocalTimeZone = compositionLocalOf { ZoneId.systemDefault() } +val LocalZoneId = compositionLocalOf { ZoneId.systemDefault() } diff --git a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index c922d9687..9c4377b9d 100644 --- a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -244,7 +244,7 @@ fun NotificationDot( fun dateFormatted(publishDate: Instant): String = DateTimeFormatter .ofLocalizedDate(FormatStyle.MEDIUM) .withLocale(Locale.getDefault()) - .withZone(LocalTimeZone.current) + .withZone(LocalZoneId.current) .format(publishDate.toJavaInstant()) @Composable From 6c7a136de20a2175a6f624931f27f1ef0a356fad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mlynari=C4=8D?= Date: Tue, 30 Jan 2024 20:29:34 +0100 Subject: [PATCH 11/65] More readable zoneId creation Change-Id: I912dc021554e4886a5d09e63799aa5c81e8fd16a --- .../samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt index 04b2ef352..99613d0f6 100644 --- a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt +++ b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt @@ -37,6 +37,7 @@ import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.shareIn import java.time.ZoneId +import java.util.TimeZone import javax.inject.Inject import javax.inject.Singleton @@ -72,6 +73,7 @@ internal class TimeZoneBroadcastMonitor @Inject constructor( intent.getStringExtra(Intent.EXTRA_TIMEZONE)?.let { zoneId -> // We need to convert it from java.util.Timezone to java.time.ZoneId ZoneId.of(zoneId, ZoneId.SHORT_IDS) + TimeZone.getTimeZone(zoneId).toZoneId() } } From e4917b133250cf9363f5c849a3d9544c8a583396 Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Thu, 16 Nov 2023 22:48:12 +0100 Subject: [PATCH 12/65] Fix `emptyResultIsReturned_withNotMatchingQuery` unit test `searchResultUiState` transitively relied on `getSearchContentsCount` updates and on `userDataRepository` to emit something. --- .../TestSearchContentsRepository.kt | 45 +++++++++---------- .../feature/search/SearchViewModelTest.kt | 5 ++- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt index 9b6151449..94ef2e384 100644 --- a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt +++ b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt @@ -21,42 +21,39 @@ import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.SearchResult import com.google.samples.apps.nowinandroid.core.model.data.Topic import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.update class TestSearchContentsRepository : SearchContentsRepository { - private val cachedTopics: MutableList = mutableListOf() - private val cachedNewsResources: MutableList = mutableListOf() + private val cachedTopics = MutableStateFlow(emptyList()) + private val cachedNewsResources = MutableStateFlow(emptyList()) override suspend fun populateFtsData() = Unit - override fun searchContents(searchQuery: String): Flow = flowOf( - SearchResult( - topics = cachedTopics.filter { - searchQuery in it.name || searchQuery in it.shortDescription || searchQuery in it.longDescription - }, - newsResources = cachedNewsResources.filter { - searchQuery in it.content || searchQuery in it.title - }, - ), - ) - - override fun getSearchContentsCount(): Flow = flow { - emit(cachedTopics.size + cachedNewsResources.size) - } + override fun searchContents(searchQuery: String): Flow = + combine(cachedTopics, cachedNewsResources) { topics, news -> + SearchResult( + topics = topics.filter { + searchQuery in it.name || searchQuery in it.shortDescription || searchQuery in it.longDescription + }, + newsResources = news.filter { + searchQuery in it.content || searchQuery in it.title + }, + ) + } + + override fun getSearchContentsCount(): Flow = combine(cachedTopics, cachedNewsResources) { topics, news -> topics.size + news.size } /** * Test only method to add the topics to the stored list in memory */ - fun addTopics(topics: List) { - cachedTopics.addAll(topics) - } + fun addTopics(topics: List) = cachedTopics.update { it + topics } /** * Test only method to add the news resources to the stored list in memory */ - fun addNewsResources(newsResources: List) { - cachedNewsResources.addAll(newsResources) - } + fun addNewsResources(newsResources: List) = + cachedNewsResources.update { newsResources } } diff --git a/feature/search/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt b/feature/search/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt index fc9c20549..da0d5654e 100644 --- a/feature/search/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt +++ b/feature/search/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt @@ -26,6 +26,7 @@ import com.google.samples.apps.nowinandroid.core.testing.data.topicsTestData import com.google.samples.apps.nowinandroid.core.testing.repository.TestRecentSearchRepository import com.google.samples.apps.nowinandroid.core.testing.repository.TestSearchContentsRepository import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository +import com.google.samples.apps.nowinandroid.core.testing.repository.emptyUserData import com.google.samples.apps.nowinandroid.core.testing.util.MainDispatcherRule import com.google.samples.apps.nowinandroid.feature.search.RecentSearchQueriesUiState.Success import com.google.samples.apps.nowinandroid.feature.search.SearchResultUiState.EmptyQuery @@ -71,6 +72,7 @@ class SearchViewModelTest { recentSearchRepository = recentSearchRepository, analyticsHelper = NoOpAnalyticsHelper(), ) + userDataRepository.setUserData(emptyUserData) } @Test @@ -100,8 +102,7 @@ class SearchViewModelTest { searchContentsRepository.addTopics(topicsTestData) val result = viewModel.searchResultUiState.value - // TODO: Figure out to get the latest emitted ui State? The result is emitted as EmptyQuery - // assertIs(result) + assertIs(result) collectJob.cancel() } From 17b006ed432a88d0b0ed23fdf4f7d0a0f76d455d Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Wed, 31 Jan 2024 10:44:18 +0100 Subject: [PATCH 13/65] Fix addNewsResources issue --- .../core/testing/repository/TestSearchContentsRepository.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt index 94ef2e384..4a3baba44 100644 --- a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt +++ b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt @@ -55,5 +55,5 @@ class TestSearchContentsRepository : SearchContentsRepository { * Test only method to add the news resources to the stored list in memory */ fun addNewsResources(newsResources: List) = - cachedNewsResources.update { newsResources } + cachedNewsResources.update { it + newsResources } } From 7a5df77bc3cab97c3a2ff13d00141d7f3bb85566 Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Wed, 31 Jan 2024 10:45:45 +0100 Subject: [PATCH 14/65] Replace comments with proper `@TestOnly` annotations --- .../testing/repository/TestSearchContentsRepository.kt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt index 4a3baba44..5436cd10f 100644 --- a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt +++ b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt @@ -24,6 +24,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.update +import org.jetbrains.annotations.TestOnly class TestSearchContentsRepository : SearchContentsRepository { @@ -46,14 +47,10 @@ class TestSearchContentsRepository : SearchContentsRepository { override fun getSearchContentsCount(): Flow = combine(cachedTopics, cachedNewsResources) { topics, news -> topics.size + news.size } - /** - * Test only method to add the topics to the stored list in memory - */ + @TestOnly fun addTopics(topics: List) = cachedTopics.update { it + topics } - /** - * Test only method to add the news resources to the stored list in memory - */ + @TestOnly fun addNewsResources(newsResources: List) = cachedNewsResources.update { it + newsResources } } From 6f2a84be82373576f52e4da94998c7b9f78829ca Mon Sep 17 00:00:00 2001 From: yongsuk Date: Wed, 31 Jan 2024 18:52:53 +0900 Subject: [PATCH 15/65] Update typo setup.sh --- tools/setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/setup.sh b/tools/setup.sh index 1467bbad0..b0f204268 100755 --- a/tools/setup.sh +++ b/tools/setup.sh @@ -35,7 +35,7 @@ cp "${GIT_ROOT}/tools/pre-push" "${GIT_DIR}/hooks/pre-push" \ cat <<-EOF Checking the following settings helps avoid miscellaneous issues: * Settings -> Editor -> General -> Remove trailing spaces on: Modified lines - * Settings -> Editor -> General -> Ensure every file ends with a line break + * Settings -> Editor -> General -> Ensure every saved file ends with a line break * Settings -> Editor -> General -> Auto Import -> Optimize imports on the fly (for both Kotlin\ and Java) EOF From e208bd0bfdaaa15a6f29559b65fa7e3226f73daa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mlynari=C4=8D?= Date: Wed, 31 Jan 2024 11:29:14 +0100 Subject: [PATCH 16/65] Use kotlinx.datetime.Timezone instead of java ZoneId Change-Id: I62c4d044b319a9b59e06bb42fd12971d992e8628 --- .../apps/nowinandroid/ui/NiaAppStateTest.kt | 4 ++-- .../samples/apps/nowinandroid/MainActivity.kt | 4 ++-- .../apps/nowinandroid/ui/NiaAppState.kt | 6 +++--- .../data/test/DefaultZoneIdTimeZoneMonitor.kt | 4 ++-- .../core/data/util/TimeZoneMonitor.kt | 19 ++++++++++--------- .../core/testing/util/TestTimeZoneMonitor.kt | 8 ++++---- .../ui/{LocalZoneId.kt => LocalTimeZone.kt} | 6 +++--- .../nowinandroid/core/ui/NewsResourceCard.kt | 3 ++- 8 files changed, 28 insertions(+), 26 deletions(-) rename core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/{LocalZoneId.kt => LocalTimeZone.kt} (83%) diff --git a/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt b/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt index 18afc6a09..732e527bb 100644 --- a/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt +++ b/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt @@ -39,9 +39,9 @@ import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest +import kotlinx.datetime.TimeZone import org.junit.Rule import org.junit.Test -import java.time.ZoneId import kotlin.test.assertEquals import kotlin.test.assertFalse import kotlin.test.assertTrue @@ -199,7 +199,7 @@ class NiaAppStateTest { timeZoneMonitor = timeZoneMonitor, ) } - val changedTz = ZoneId.of("Europe/Prague") + val changedTz = TimeZone.of("Europe/Prague") backgroundScope.launch { state.currentTimeZone.collect() } timeZoneMonitor.setTimeZone(changedTz) assertEquals( diff --git a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt index 0bf45f125..afe3b51eb 100644 --- a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt +++ b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt @@ -47,7 +47,7 @@ import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand -import com.google.samples.apps.nowinandroid.core.ui.LocalZoneId +import com.google.samples.apps.nowinandroid.core.ui.LocalTimeZone import com.google.samples.apps.nowinandroid.ui.NiaApp import com.google.samples.apps.nowinandroid.ui.rememberNiaAppState import dagger.hilt.android.AndroidEntryPoint @@ -144,7 +144,7 @@ class MainActivity : ComponentActivity() { CompositionLocalProvider( LocalAnalyticsHelper provides analyticsHelper, - LocalZoneId provides currentZoneId, + LocalTimeZone provides currentZoneId, ) { NiaTheme( darkTheme = darkTheme, diff --git a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt index ffd0c16ec..ec2be6511 100644 --- a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt +++ b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt @@ -51,7 +51,7 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn -import java.time.ZoneId +import kotlinx.datetime.TimeZone @Composable fun rememberNiaAppState( @@ -140,11 +140,11 @@ class NiaAppState( initialValue = emptySet(), ) - val currentTimeZone = timeZoneMonitor.currentZoneId + val currentTimeZone = timeZoneMonitor.currentTimeZone .stateIn( coroutineScope, SharingStarted.WhileSubscribed(5_000), - ZoneId.systemDefault(), + TimeZone.currentSystemDefault(), ) /** diff --git a/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/DefaultZoneIdTimeZoneMonitor.kt b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/DefaultZoneIdTimeZoneMonitor.kt index ee8fe97a3..5a21ae337 100644 --- a/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/DefaultZoneIdTimeZoneMonitor.kt +++ b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/DefaultZoneIdTimeZoneMonitor.kt @@ -19,9 +19,9 @@ package com.google.samples.apps.nowinandroid.core.data.test import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf -import java.time.ZoneId +import kotlinx.datetime.TimeZone import javax.inject.Inject class DefaultZoneIdTimeZoneMonitor @Inject constructor() : TimeZoneMonitor { - override val currentZoneId: Flow = flowOf(ZoneId.of("Europe/Warsaw")) + override val currentTimeZone: Flow = flowOf(TimeZone.of("Europe/Warsaw")) } diff --git a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt index 99613d0f6..f7cc73565 100644 --- a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt +++ b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt @@ -34,10 +34,11 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.conflate import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.shareIn +import kotlinx.datetime.TimeZone import java.time.ZoneId -import java.util.TimeZone import javax.inject.Inject import javax.inject.Singleton @@ -46,7 +47,7 @@ import javax.inject.Singleton * It always emits at least once with default setting and then for each TZ change. */ interface TimeZoneMonitor { - val currentZoneId: Flow + val currentTimeZone: Flow } @Singleton @@ -56,10 +57,10 @@ internal class TimeZoneBroadcastMonitor @Inject constructor( @Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher, ) : TimeZoneMonitor { - override val currentZoneId: SharedFlow = - callbackFlow { + override val currentTimeZone: SharedFlow = + callbackFlow { // Send the default time zone first. - trySend(ZoneId.systemDefault()) + trySend(TimeZone.currentSystemDefault()) // Registers BroadcastReceiver for the TimeZone changes val receiver = object : BroadcastReceiver() { @@ -70,15 +71,15 @@ internal class TimeZoneBroadcastMonitor @Inject constructor( null } else { // Starting Android R we also get the new TimeZone. - intent.getStringExtra(Intent.EXTRA_TIMEZONE)?.let { zoneId -> + intent.getStringExtra(Intent.EXTRA_TIMEZONE)?.let { timeZoneId -> // We need to convert it from java.util.Timezone to java.time.ZoneId - ZoneId.of(zoneId, ZoneId.SHORT_IDS) - TimeZone.getTimeZone(zoneId).toZoneId() + val zoneId = ZoneId.of(timeZoneId, ZoneId.SHORT_IDS) + TimeZone.of(zoneId.id) } } // If there isn't a zoneId in the intent, fallback to the systemDefault, which should also reflect the change - trySend(zoneIdFromIntent ?: ZoneId.systemDefault()) + trySend(zoneIdFromIntent ?: TimeZone.currentSystemDefault()) } } diff --git a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/TestTimeZoneMonitor.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/TestTimeZoneMonitor.kt index 1d7f21543..cc71ab2ca 100644 --- a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/TestTimeZoneMonitor.kt +++ b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/TestTimeZoneMonitor.kt @@ -19,22 +19,22 @@ package com.google.samples.apps.nowinandroid.core.testing.util import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow -import java.time.ZoneId +import kotlinx.datetime.TimeZone class TestTimeZoneMonitor : TimeZoneMonitor { private val timeZoneFlow = MutableStateFlow(defaultTimeZone) - override val currentZoneId: Flow = timeZoneFlow + override val currentTimeZone: Flow = timeZoneFlow /** * A test-only API to set the from tests. */ - fun setTimeZone(zoneId: ZoneId) { + fun setTimeZone(zoneId: TimeZone) { timeZoneFlow.value = zoneId } companion object { - val defaultTimeZone: ZoneId = ZoneId.of("Europe/Warsaw") + val defaultTimeZone: TimeZone = TimeZone.of("Europe/Warsaw") } } diff --git a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/LocalZoneId.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/LocalTimeZone.kt similarity index 83% rename from core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/LocalZoneId.kt rename to core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/LocalTimeZone.kt index 54aa7931d..2d9948488 100644 --- a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/LocalZoneId.kt +++ b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/LocalTimeZone.kt @@ -17,10 +17,10 @@ package com.google.samples.apps.nowinandroid.core.ui import androidx.compose.runtime.compositionLocalOf -import java.time.ZoneId +import kotlinx.datetime.TimeZone /** - * ZoneId that can be provided with the TimeZoneMonitor. + * TimeZone that can be provided with the TimeZoneMonitor. * This way, it's not needed to pass every single composable the time zone to show in UI. */ -val LocalZoneId = compositionLocalOf { ZoneId.systemDefault() } +val LocalTimeZone = compositionLocalOf { TimeZone.currentSystemDefault() } diff --git a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index 9c4377b9d..2b22c7ea2 100644 --- a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -69,6 +69,7 @@ import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource import kotlinx.datetime.Instant import kotlinx.datetime.toJavaInstant +import kotlinx.datetime.toJavaZoneId import java.time.format.DateTimeFormatter import java.time.format.FormatStyle import java.util.Locale @@ -244,7 +245,7 @@ fun NotificationDot( fun dateFormatted(publishDate: Instant): String = DateTimeFormatter .ofLocalizedDate(FormatStyle.MEDIUM) .withLocale(Locale.getDefault()) - .withZone(LocalZoneId.current) + .withZone(LocalTimeZone.current.toJavaZoneId()) .format(publishDate.toJavaInstant()) @Composable From 251b1bbc2c8528785adcf2d63142250bdc959dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mlynari=C4=8D?= Date: Wed, 31 Jan 2024 11:32:49 +0100 Subject: [PATCH 17/65] Use androidx.tracing everywhere Change-Id: I9a77c4434d271e2e23700823f9f513aa61d177f8 --- .../src/main/kotlin/AndroidFeatureConventionPlugin.kt | 2 ++ .../src/main/kotlin/AndroidLibraryConventionPlugin.kt | 3 +++ .../apps/nowinandroid/core/data/util/TimeZoneMonitor.kt | 4 ++-- .../samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt | 2 +- gradle/libs.versions.toml | 2 +- 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt index 7a334beb3..8a76a1ac9 100644 --- a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt @@ -44,6 +44,8 @@ class AndroidFeatureConventionPlugin : Plugin { add("implementation", libs.findLibrary("androidx.hilt.navigation.compose").get()) add("implementation", libs.findLibrary("androidx.lifecycle.runtimeCompose").get()) add("implementation", libs.findLibrary("androidx.lifecycle.viewModelCompose").get()) + + add("implementation", libs.findLibrary("androidx.tracing.ktx").get()) } } } diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt index 8eb329f58..d442d94ef 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt @@ -21,6 +21,7 @@ import com.google.samples.apps.nowinandroid.configureGradleManagedDevices import com.google.samples.apps.nowinandroid.configureKotlinAndroid import com.google.samples.apps.nowinandroid.configurePrintApksTask import com.google.samples.apps.nowinandroid.disableUnnecessaryAndroidTests +import com.google.samples.apps.nowinandroid.libs import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.configure @@ -51,6 +52,8 @@ class AndroidLibraryConventionPlugin : Plugin { } dependencies { add("testImplementation", kotlin("test")) + + add("implementation", libs.findLibrary("androidx.tracing.ktx").get()) } } } diff --git a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt index f7cc73565..d75f81efc 100644 --- a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt +++ b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt @@ -22,7 +22,7 @@ import android.content.Intent import android.content.IntentFilter import android.os.Build.VERSION import android.os.Build.VERSION_CODES -import androidx.core.os.trace +import androidx.tracing.trace import com.google.samples.apps.nowinandroid.core.network.Dispatcher import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO import com.google.samples.apps.nowinandroid.core.network.di.ApplicationScope @@ -58,7 +58,7 @@ internal class TimeZoneBroadcastMonitor @Inject constructor( ) : TimeZoneMonitor { override val currentTimeZone: SharedFlow = - callbackFlow { + callbackFlow { // Send the default time zone first. trySend(TimeZone.currentSystemDefault()) diff --git a/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt b/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt index 30134715b..e8b19594f 100644 --- a/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt +++ b/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt @@ -81,7 +81,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.max import androidx.compose.ui.unit.sp -import androidx.compose.ui.util.trace +import androidx.tracing.trace import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.google.accompanist.permissions.ExperimentalPermissionsApi diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5bcdaf41c..d85a8c3ad 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -24,7 +24,7 @@ androidxTestCore = "1.5.0" androidxTestExt = "1.1.5" androidxTestRules = "1.5.0" androidxTestRunner = "1.5.2" -androidxTracing = "1.1.0" +androidxTracing = "1.3.0-alpha02" androidxUiAutomator = "2.2.0" androidxWindowManager = "1.2.0" androidxWork = "2.9.0" From 74bba93730a050e7e224533863d31ddae0566254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mlynari=C4=8D?= Date: Wed, 31 Jan 2024 12:11:22 +0100 Subject: [PATCH 18/65] Fix spotless Change-Id: I26a64df036d17bcd455e782306fb31c099dd53ed --- .../samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt b/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt index e8b19594f..e1418d747 100644 --- a/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt +++ b/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt @@ -81,9 +81,9 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.max import androidx.compose.ui.unit.sp -import androidx.tracing.trace import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.tracing.trace import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.PermissionStatus.Denied import com.google.accompanist.permissions.rememberPermissionState From 37af1797160f5e8f394f4cc472b205a264fbad5f Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Sat, 6 Jan 2024 10:50:26 +0100 Subject: [PATCH 19/65] Move `:core:data` fake repositories to `:core:data-test` Now that these fake implementations are no longer used in the production source code (only in tests), we can safely extract them out of this module. Hopefully, we'll later be able to use Kotlin testFixtures for that. References: - #709 - #875 --- .../nowinandroid/core/data/test/TestDataModule.kt | 12 ++++++------ .../core/data/test/repository}/FakeNewsRepository.kt | 4 ++-- .../test/repository}/FakeRecentSearchRepository.kt | 4 ++-- .../test/repository}/FakeSearchContentsRepository.kt | 4 ++-- .../data/test/repository}/FakeTopicsRepository.kt | 4 ++-- .../data/test/repository}/FakeUserDataRepository.kt | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) rename core/{data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake => data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository}/FakeNewsRepository.kt (96%) rename core/{data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake => data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository}/FakeRecentSearchRepository.kt (88%) rename core/{data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake => data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository}/FakeSearchContentsRepository.kt (87%) rename core/{data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake => data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository}/FakeTopicsRepository.kt (94%) rename core/{data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake => data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository}/FakeUserDataRepository.kt (95%) diff --git a/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/TestDataModule.kt b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/TestDataModule.kt index 2ec2bcf9c..0ae4865ec 100644 --- a/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/TestDataModule.kt +++ b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/TestDataModule.kt @@ -22,11 +22,11 @@ import com.google.samples.apps.nowinandroid.core.data.repository.RecentSearchRep import com.google.samples.apps.nowinandroid.core.data.repository.SearchContentsRepository import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepository import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository -import com.google.samples.apps.nowinandroid.core.data.repository.fake.FakeNewsRepository -import com.google.samples.apps.nowinandroid.core.data.repository.fake.FakeRecentSearchRepository -import com.google.samples.apps.nowinandroid.core.data.repository.fake.FakeSearchContentsRepository -import com.google.samples.apps.nowinandroid.core.data.repository.fake.FakeTopicsRepository -import com.google.samples.apps.nowinandroid.core.data.repository.fake.FakeUserDataRepository +import com.google.samples.apps.nowinandroid.core.data.test.repository.FakeNewsRepository +import com.google.samples.apps.nowinandroid.core.data.test.repository.FakeRecentSearchRepository +import com.google.samples.apps.nowinandroid.core.data.test.repository.FakeSearchContentsRepository +import com.google.samples.apps.nowinandroid.core.data.test.repository.FakeTopicsRepository +import com.google.samples.apps.nowinandroid.core.data.test.repository.FakeUserDataRepository import com.google.samples.apps.nowinandroid.core.data.util.NetworkMonitor import dagger.Binds import dagger.Module @@ -38,7 +38,7 @@ import dagger.hilt.testing.TestInstallIn components = [SingletonComponent::class], replaces = [DataModule::class], ) -interface TestDataModule { +internal interface TestDataModule { @Binds fun bindsTopicRepository( fakeTopicsRepository: FakeTopicsRepository, diff --git a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeNewsRepository.kt b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository/FakeNewsRepository.kt similarity index 96% rename from core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeNewsRepository.kt rename to core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository/FakeNewsRepository.kt index 39ad05d1e..5ceff4dd0 100644 --- a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeNewsRepository.kt +++ b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository/FakeNewsRepository.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.samples.apps.nowinandroid.core.data.repository.fake +package com.google.samples.apps.nowinandroid.core.data.test.repository import com.google.samples.apps.nowinandroid.core.data.Synchronizer import com.google.samples.apps.nowinandroid.core.data.model.asEntity @@ -39,7 +39,7 @@ import javax.inject.Inject * This allows us to run the app with fake data, without needing an internet connection or working * backend. */ -class FakeNewsRepository @Inject constructor( +internal class FakeNewsRepository @Inject constructor( @Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher, private val datasource: FakeNiaNetworkDataSource, ) : NewsRepository { diff --git a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeRecentSearchRepository.kt b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository/FakeRecentSearchRepository.kt similarity index 88% rename from core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeRecentSearchRepository.kt rename to core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository/FakeRecentSearchRepository.kt index 025b51f68..b8d949efe 100644 --- a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeRecentSearchRepository.kt +++ b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository/FakeRecentSearchRepository.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.samples.apps.nowinandroid.core.data.repository.fake +package com.google.samples.apps.nowinandroid.core.data.test.repository import com.google.samples.apps.nowinandroid.core.data.model.RecentSearchQuery import com.google.samples.apps.nowinandroid.core.data.repository.RecentSearchRepository @@ -25,7 +25,7 @@ import javax.inject.Inject /** * Fake implementation of the [RecentSearchRepository] */ -class FakeRecentSearchRepository @Inject constructor() : RecentSearchRepository { +internal class FakeRecentSearchRepository @Inject constructor() : RecentSearchRepository { override suspend fun insertOrReplaceRecentSearch(searchQuery: String) = Unit override fun getRecentSearchQueries(limit: Int): Flow> = diff --git a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeSearchContentsRepository.kt b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository/FakeSearchContentsRepository.kt similarity index 87% rename from core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeSearchContentsRepository.kt rename to core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository/FakeSearchContentsRepository.kt index 65cced452..1feeb6dcc 100644 --- a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeSearchContentsRepository.kt +++ b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository/FakeSearchContentsRepository.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.samples.apps.nowinandroid.core.data.repository.fake +package com.google.samples.apps.nowinandroid.core.data.test.repository import com.google.samples.apps.nowinandroid.core.data.repository.SearchContentsRepository import com.google.samples.apps.nowinandroid.core.model.data.SearchResult @@ -25,7 +25,7 @@ import javax.inject.Inject /** * Fake implementation of the [SearchContentsRepository] */ -class FakeSearchContentsRepository @Inject constructor() : SearchContentsRepository { +internal class FakeSearchContentsRepository @Inject constructor() : SearchContentsRepository { override suspend fun populateFtsData() = Unit override fun searchContents(searchQuery: String): Flow = flowOf() diff --git a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeTopicsRepository.kt b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository/FakeTopicsRepository.kt similarity index 94% rename from core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeTopicsRepository.kt rename to core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository/FakeTopicsRepository.kt index 0eefc8451..f8ebca29e 100644 --- a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeTopicsRepository.kt +++ b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository/FakeTopicsRepository.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.samples.apps.nowinandroid.core.data.repository.fake +package com.google.samples.apps.nowinandroid.core.data.test.repository import com.google.samples.apps.nowinandroid.core.data.Synchronizer import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepository @@ -36,7 +36,7 @@ import javax.inject.Inject * This allows us to run the app with fake data, without needing an internet connection or working * backend. */ -class FakeTopicsRepository @Inject constructor( +internal class FakeTopicsRepository @Inject constructor( @Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher, private val datasource: FakeNiaNetworkDataSource, ) : TopicsRepository { diff --git a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeUserDataRepository.kt b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository/FakeUserDataRepository.kt similarity index 95% rename from core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeUserDataRepository.kt rename to core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository/FakeUserDataRepository.kt index a9da29b56..cdd23429f 100644 --- a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeUserDataRepository.kt +++ b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/repository/FakeUserDataRepository.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.samples.apps.nowinandroid.core.data.repository.fake +package com.google.samples.apps.nowinandroid.core.data.test.repository import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository import com.google.samples.apps.nowinandroid.core.datastore.NiaPreferencesDataSource @@ -30,7 +30,7 @@ import javax.inject.Inject * This allows us to run the app with fake data, without needing an internet connection or working * backend. */ -class FakeUserDataRepository @Inject constructor( +internal class FakeUserDataRepository @Inject constructor( private val niaPreferencesDataSource: NiaPreferencesDataSource, ) : UserDataRepository { From 8f5c475aab2a3b43e8ee6c88eb83a9cfe79b2ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mlynari=C4=8D?= Date: Tue, 6 Feb 2024 08:53:04 +0100 Subject: [PATCH 20/65] Rename currentTimezone variable Change-Id: I92630f6851b0253294a8d3ec2e5b3cbe7db74b4d --- .../com/google/samples/apps/nowinandroid/MainActivity.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt index afe3b51eb..ad95c297f 100644 --- a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt +++ b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt @@ -140,11 +140,11 @@ class MainActivity : ComponentActivity() { timeZoneMonitor = timeZoneMonitor, ) - val currentZoneId by appState.currentTimeZone.collectAsStateWithLifecycle() + val currentTimeZone by appState.currentTimeZone.collectAsStateWithLifecycle() CompositionLocalProvider( LocalAnalyticsHelper provides analyticsHelper, - LocalTimeZone provides currentZoneId, + LocalTimeZone provides currentTimeZone, ) { NiaTheme( darkTheme = darkTheme, From 5f994ec7cdd99106d40c7b3d322c64049acd7234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mlynari=C4=8D?= Date: Tue, 6 Feb 2024 08:56:43 +0100 Subject: [PATCH 21/65] Update dependency guard baseline Change-Id: I2557753f1eb4c6845aca6473a6aba5b7e758ebbf --- .../dependencies/releaseRuntimeClasspath.txt | 7 ++++--- app/dependencies/prodReleaseRuntimeClasspath.txt | 10 ++++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt b/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt index 10f2dfa32..e59cc53bc 100644 --- a/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt +++ b/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt @@ -70,7 +70,8 @@ androidx.profileinstaller:profileinstaller:1.3.1 androidx.savedstate:savedstate-ktx:1.2.1 androidx.savedstate:savedstate:1.2.1 androidx.startup:startup-runtime:1.1.1 -androidx.tracing:tracing:1.0.0 +androidx.tracing:tracing-ktx:1.3.0-alpha02 +androidx.tracing:tracing:1.3.0-alpha02 androidx.vectordrawable:vectordrawable-animated:1.1.0 androidx.vectordrawable:vectordrawable:1.1.0 androidx.versionedparcelable:versionedparcelable:1.1.1 @@ -90,10 +91,10 @@ io.coil-kt:coil-compose-base:2.5.0 io.coil-kt:coil-compose:2.5.0 io.coil-kt:coil:2.5.0 javax.inject:javax.inject:1 -org.jetbrains.kotlin:kotlin-stdlib-common:1.9.21 +org.jetbrains.kotlin:kotlin-stdlib-common:1.9.22 org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.10 org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.10 -org.jetbrains.kotlin:kotlin-stdlib:1.9.21 +org.jetbrains.kotlin:kotlin-stdlib:1.9.22 org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3 org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3 diff --git a/app/dependencies/prodReleaseRuntimeClasspath.txt b/app/dependencies/prodReleaseRuntimeClasspath.txt index e9e3ebf8e..6eb888042 100644 --- a/app/dependencies/prodReleaseRuntimeClasspath.txt +++ b/app/dependencies/prodReleaseRuntimeClasspath.txt @@ -32,6 +32,7 @@ androidx.compose.material:material-ripple:1.5.4 androidx.compose.runtime:runtime-android:1.5.4 androidx.compose.runtime:runtime-saveable-android:1.5.4 androidx.compose.runtime:runtime-saveable:1.5.4 +androidx.compose.runtime:runtime-tracing:1.0.0-beta01 androidx.compose.runtime:runtime:1.5.4 androidx.compose.ui:ui-android:1.5.4 androidx.compose.ui:ui-geometry-android:1.5.4 @@ -105,8 +106,9 @@ androidx.savedstate:savedstate:1.2.1 androidx.sqlite:sqlite-framework:2.4.0 androidx.sqlite:sqlite:2.4.0 androidx.startup:startup-runtime:1.1.1 -androidx.tracing:tracing-ktx:1.1.0 -androidx.tracing:tracing:1.1.0 +androidx.tracing:tracing-ktx:1.3.0-alpha02 +androidx.tracing:tracing-perfetto:1.0.0 +androidx.tracing:tracing:1.3.0-alpha02 androidx.vectordrawable:vectordrawable-animated:1.1.0 androidx.vectordrawable:vectordrawable:1.1.0 androidx.versionedparcelable:versionedparcelable:1.1.1 @@ -185,10 +187,10 @@ io.github.aakira:napier-android:1.4.1 io.github.aakira:napier:1.4.1 javax.inject:javax.inject:1 org.checkerframework:checker-qual:3.12.0 -org.jetbrains.kotlin:kotlin-stdlib-common:1.9.21 +org.jetbrains.kotlin:kotlin-stdlib-common:1.9.22 org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.10 org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.10 -org.jetbrains.kotlin:kotlin-stdlib:1.9.21 +org.jetbrains.kotlin:kotlin-stdlib:1.9.22 org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3 org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3 org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3 From 77d4f5f57f8164ff8ebb3cee1defa1fac3aec73e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mlynari=C4=8D?= Date: Tue, 6 Feb 2024 15:04:24 +0100 Subject: [PATCH 22/65] Use trySend multiple times Change-Id: Ie00c4180d07fc4bb9d457647f3b7ddadd5a3c032 --- .../com/google/samples/apps/nowinandroid/ui/NiaAppState.kt | 2 +- .../apps/nowinandroid/core/data/util/TimeZoneMonitor.kt | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt index ec2be6511..d423adfbf 100644 --- a/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt +++ b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt @@ -89,7 +89,7 @@ class NiaAppState( val windowSizeClass: WindowSizeClass, networkMonitor: NetworkMonitor, userNewsResourceRepository: UserNewsResourceRepository, - private val timeZoneMonitor: TimeZoneMonitor, + timeZoneMonitor: TimeZoneMonitor, ) { val currentDestination: NavDestination? @Composable get() = navController diff --git a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt index d75f81efc..6e206e67c 100644 --- a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt +++ b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt @@ -35,6 +35,7 @@ import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.callbackFlow import kotlinx.coroutines.flow.conflate +import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.shareIn import kotlinx.datetime.TimeZone @@ -87,10 +88,16 @@ internal class TimeZoneBroadcastMonitor @Inject constructor( context.registerReceiver(receiver, IntentFilter(Intent.ACTION_TIMEZONE_CHANGED)) } + // Send here again, because registering the Broadcast Receiver can take up to several milliseconds. + // This way, we can reduce the likelihood that a TZ change wouldn't be caught with the Broadcast Receiver. + trySend(TimeZone.currentSystemDefault()) + awaitClose { context.unregisterReceiver(receiver) } } + // We use to prevent multiple emissions of the same type, because we use trySend multiple times. + .distinctUntilChanged() .conflate() .flowOn(ioDispatcher) // Sharing the callback to prevent multiple BroadcastReceivers being registered From 8e959e98034655d882f35c3bbab118f9e1815250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mlynari=C4=8D?= Date: Tue, 6 Feb 2024 15:07:12 +0100 Subject: [PATCH 23/65] Improve converting to kotlin timezone Change-Id: I2af929c341cb274ae6b93bb8dffe696de6ed1c63 --- .../apps/nowinandroid/core/data/util/TimeZoneMonitor.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt index 6e206e67c..031bc9388 100644 --- a/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt +++ b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/TimeZoneMonitor.kt @@ -39,6 +39,7 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.shareIn import kotlinx.datetime.TimeZone +import kotlinx.datetime.toKotlinTimeZone import java.time.ZoneId import javax.inject.Inject import javax.inject.Singleton @@ -75,7 +76,8 @@ internal class TimeZoneBroadcastMonitor @Inject constructor( intent.getStringExtra(Intent.EXTRA_TIMEZONE)?.let { timeZoneId -> // We need to convert it from java.util.Timezone to java.time.ZoneId val zoneId = ZoneId.of(timeZoneId, ZoneId.SHORT_IDS) - TimeZone.of(zoneId.id) + // Convert to kotlinx.datetime.TimeZone + zoneId.toKotlinTimeZone() } } From 0b47a61fa3571810417f4743a44ed6edc3b670b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Alc=C3=A9rreca?= Date: Wed, 7 Feb 2024 10:28:34 +0100 Subject: [PATCH 24/65] Dpm --- .github/workflows/Build.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/Build.yaml b/.github/workflows/Build.yaml index fa3a77f55..68b1f5f64 100644 --- a/.github/workflows/Build.yaml +++ b/.github/workflows/Build.yaml @@ -176,6 +176,12 @@ jobs: - name: Build projects before running emulator run: ./gradlew packageDemoDebug packageDemoDebugAndroidTest + - name: Print available space + run: df -h + + - name: Print disk usage + run: du -h -d 2 /home/runner/ + - name: Run instrumentation tests uses: reactivecircus/android-emulator-runner@v2 with: From e8368a8a82113889aba7db35f191b9e0609ad03a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Alc=C3=A9rreca?= Date: Wed, 7 Feb 2024 10:51:52 +0100 Subject: [PATCH 25/65] Figuring out what is using 66Gb in the runner --- .github/workflows/Build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Build.yaml b/.github/workflows/Build.yaml index 68b1f5f64..d79dd2a5e 100644 --- a/.github/workflows/Build.yaml +++ b/.github/workflows/Build.yaml @@ -180,7 +180,7 @@ jobs: run: df -h - name: Print disk usage - run: du -h -d 2 /home/runner/ + run: du -h -d 2 / - name: Run instrumentation tests uses: reactivecircus/android-emulator-runner@v2 From c9daa31f74b902c2d44e0b65335b8187e101df3c Mon Sep 17 00:00:00 2001 From: Don Turner Date: Thu, 8 Feb 2024 18:38:51 +0000 Subject: [PATCH 26/65] Update Lifecycle to 2.7.0. Use new LifecycleEventEffect. Change-Id: I71e7aa521f22499fd3f3e9f3ac7c81658f3abc3a --- .../kotlin/AndroidFeatureConventionPlugin.kt | 2 ++ .../feature/bookmarks/BookmarksScreenTest.kt | 31 +++++++++++++++++++ .../feature/bookmarks/BookmarksScreen.kt | 15 ++------- gradle/libs.versions.toml | 3 +- 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt index 7a334beb3..6def4e630 100644 --- a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt @@ -44,6 +44,8 @@ class AndroidFeatureConventionPlugin : Plugin { add("implementation", libs.findLibrary("androidx.hilt.navigation.compose").get()) add("implementation", libs.findLibrary("androidx.lifecycle.runtimeCompose").get()) add("implementation", libs.findLibrary("androidx.lifecycle.viewModelCompose").get()) + + add("androidTestImplementation", libs.findLibrary("androidx.lifecycle.runtimeTesting").get()) } } } diff --git a/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt b/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt index 3d684f9d1..197a447fe 100644 --- a/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt +++ b/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt @@ -17,6 +17,8 @@ package com.google.samples.apps.nowinandroid.feature.bookmarks import androidx.activity.ComponentActivity +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.test.assertCountEquals import androidx.compose.ui.test.assertHasClickAction import androidx.compose.ui.test.filter @@ -30,8 +32,11 @@ import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performScrollToNode +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.testing.TestLifecycleOwner import com.google.samples.apps.nowinandroid.core.testing.data.userNewsResourcesTestData import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState +import kotlinx.coroutines.test.runTest import org.junit.Rule import org.junit.Test import kotlin.test.assertEquals @@ -166,4 +171,30 @@ class BookmarksScreenTest { ) .assertExists() } + + @Test + fun feed_whenLifecycleStops_undoBookmarkedStateIsCleared() = runTest { + + var undoStateCleared = false + val testLifecycleOwner = TestLifecycleOwner(initialState = Lifecycle.State.STARTED) + + composeTestRule.setContent { + CompositionLocalProvider(LocalLifecycleOwner provides testLifecycleOwner){ + BookmarksScreen( + feedState = NewsFeedUiState.Success(emptyList()), + onShowSnackbar = { _, _ -> false }, + removeFromBookmarks = {}, + onTopicClick = {}, + onNewsResourceViewed = {}, + clearUndoState = { + undoStateCleared = true + } + ) + } + } + + assertEquals(false, undoStateCleared) + testLifecycleOwner.handleLifecycleEvent(event = Lifecycle.Event.ON_STOP) + assertEquals(true, undoStateCleared) + } } diff --git a/feature/bookmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt b/feature/bookmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt index 5b54db7cd..7c229c5ea 100644 --- a/feature/bookmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt +++ b/feature/bookmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt @@ -42,14 +42,12 @@ import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridS import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -60,7 +58,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleEventObserver +import androidx.lifecycle.compose.LifecycleEventEffect import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadingWheel import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollbar.DraggableScrollbar @@ -128,15 +126,8 @@ internal fun BookmarksScreen( } } - val lifecycleOwner = LocalLifecycleOwner.current - DisposableEffect(lifecycleOwner) { - val observer = LifecycleEventObserver { _, event -> - if (event == Lifecycle.Event.ON_STOP) { - clearUndoState() - } - } - lifecycleOwner.lifecycle.addObserver(observer) - onDispose { lifecycleOwner.lifecycle.removeObserver(observer) } + LifecycleEventEffect(Lifecycle.Event.ON_STOP) { + clearUndoState() } when (feedState) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 795510bce..f0b5aa642 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ androidxCoreSplashscreen = "1.0.1" androidxDataStore = "1.0.0" androidxEspresso = "3.5.1" androidxHiltNavigationCompose = "1.0.0" -androidxLifecycle = "2.6.2" +androidxLifecycle = "2.7.0" androidxMacroBenchmark = "1.2.2" androidxMetrics = "1.0.0-alpha04" androidxNavigation = "2.7.4" @@ -82,6 +82,7 @@ androidx-core-splashscreen = { group = "androidx.core", name = "core-splashscree androidx-dataStore-core = { group = "androidx.datastore", name = "datastore", version.ref = "androidxDataStore" } androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "androidxHiltNavigationCompose" } androidx-lifecycle-runtimeCompose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "androidxLifecycle" } +androidx-lifecycle-runtimeTesting = { group = "androidx.lifecycle", name = "lifecycle-runtime-testing", version.ref = "androidxLifecycle" } androidx-lifecycle-viewModelCompose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "androidxLifecycle" } androidx-metrics = { group = "androidx.metrics", name = "metrics-performance", version.ref = "androidxMetrics" } androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "androidxNavigation" } From 4f8c96c5611caf73f003c2bdce40e19056e2f270 Mon Sep 17 00:00:00 2001 From: Don Turner Date: Mon, 19 Feb 2024 11:46:22 +0000 Subject: [PATCH 27/65] Fix formatting Change-Id: I674d32bc0f1921c431717dbf0f41a74f632322b3 --- .../nowinandroid/feature/bookmarks/BookmarksScreenTest.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt b/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt index 197a447fe..40f54e4a7 100644 --- a/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt +++ b/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt @@ -174,12 +174,11 @@ class BookmarksScreenTest { @Test fun feed_whenLifecycleStops_undoBookmarkedStateIsCleared() = runTest { - var undoStateCleared = false val testLifecycleOwner = TestLifecycleOwner(initialState = Lifecycle.State.STARTED) composeTestRule.setContent { - CompositionLocalProvider(LocalLifecycleOwner provides testLifecycleOwner){ + CompositionLocalProvider(LocalLifecycleOwner provides testLifecycleOwner) { BookmarksScreen( feedState = NewsFeedUiState.Success(emptyList()), onShowSnackbar = { _, _ -> false }, @@ -188,7 +187,7 @@ class BookmarksScreenTest { onNewsResourceViewed = {}, clearUndoState = { undoStateCleared = true - } + }, ) } } From 541262b6bbe80245e3ccde06d75904a9c10ba4c4 Mon Sep 17 00:00:00 2001 From: dturner Date: Mon, 19 Feb 2024 12:00:16 +0000 Subject: [PATCH 28/65] =?UTF-8?q?=F0=9F=A4=96=20Updates=20baselines=20for?= =?UTF-8?q?=20Dependency=20Guard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prodReleaseRuntimeClasspath.txt | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/app/dependencies/prodReleaseRuntimeClasspath.txt b/app/dependencies/prodReleaseRuntimeClasspath.txt index 759fba4a6..eaeff771a 100644 --- a/app/dependencies/prodReleaseRuntimeClasspath.txt +++ b/app/dependencies/prodReleaseRuntimeClasspath.txt @@ -71,19 +71,20 @@ androidx.hilt:hilt-navigation:1.0.0 androidx.hilt:hilt-work:1.1.0 androidx.interpolator:interpolator:1.0.0 androidx.legacy:legacy-support-core-utils:1.0.0 -androidx.lifecycle:lifecycle-common-java8:2.6.2 -androidx.lifecycle:lifecycle-common:2.6.2 -androidx.lifecycle:lifecycle-livedata-core:2.6.2 -androidx.lifecycle:lifecycle-livedata:2.6.2 -androidx.lifecycle:lifecycle-process:2.6.2 -androidx.lifecycle:lifecycle-runtime-compose:2.6.2 -androidx.lifecycle:lifecycle-runtime-ktx:2.6.2 -androidx.lifecycle:lifecycle-runtime:2.6.2 -androidx.lifecycle:lifecycle-service:2.6.2 -androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2 -androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2 -androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.2 -androidx.lifecycle:lifecycle-viewmodel:2.6.2 +androidx.lifecycle:lifecycle-common-java8:2.7.0 +androidx.lifecycle:lifecycle-common:2.7.0 +androidx.lifecycle:lifecycle-livedata-core-ktx:2.7.0 +androidx.lifecycle:lifecycle-livedata-core:2.7.0 +androidx.lifecycle:lifecycle-livedata:2.7.0 +androidx.lifecycle:lifecycle-process:2.7.0 +androidx.lifecycle:lifecycle-runtime-compose:2.7.0 +androidx.lifecycle:lifecycle-runtime-ktx:2.7.0 +androidx.lifecycle:lifecycle-runtime:2.7.0 +androidx.lifecycle:lifecycle-service:2.7.0 +androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0 +androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0 +androidx.lifecycle:lifecycle-viewmodel-savedstate:2.7.0 +androidx.lifecycle:lifecycle-viewmodel:2.7.0 androidx.loader:loader:1.0.0 androidx.localbroadcastmanager:localbroadcastmanager:1.0.0 androidx.metrics:metrics-performance:1.0.0-alpha04 From f5ccb99e8ad07a90877347ebe0b9c2556ac3aa36 Mon Sep 17 00:00:00 2001 From: Don Turner Date: Mon, 19 Feb 2024 16:29:21 +0000 Subject: [PATCH 29/65] Update Compose BOM to 2024.02.00. Fixes #1218 Change-Id: I838b81bf8e7fd7cb135f422653a8d8041829b28b --- .../samples/apps/nowinandroid/core/result/ResultKtTest.kt | 2 +- .../apps/nowinandroid/core/designsystem/component/Chip.kt | 2 ++ .../core/designsystem/component/LoadingWheel.kt | 4 ++-- .../apps/nowinandroid/core/designsystem/component/Tabs.kt | 2 +- .../apps/nowinandroid/core/designsystem/icon/NiaIcons.kt | 6 +++--- .../apps/nowinandroid/feature/search/SearchViewModelTest.kt | 2 +- .../apps/nowinandroid/feature/settings/SettingsDialog.kt | 6 +++--- gradle/libs.versions.toml | 2 +- 8 files changed, 14 insertions(+), 12 deletions(-) diff --git a/core/common/src/test/kotlin/com/google/samples/apps/nowinandroid/core/result/ResultKtTest.kt b/core/common/src/test/kotlin/com/google/samples/apps/nowinandroid/core/result/ResultKtTest.kt index 4f1229e9d..2c3c7b763 100644 --- a/core/common/src/test/kotlin/com/google/samples/apps/nowinandroid/core/result/ResultKtTest.kt +++ b/core/common/src/test/kotlin/com/google/samples/apps/nowinandroid/core/result/ResultKtTest.kt @@ -38,7 +38,7 @@ class ResultKtTest { when (val errorResult = awaitItem()) { is Result.Error -> assertEquals( "Test Done", - errorResult.exception?.message, + errorResult.exception.message, ) Result.Loading, is Result.Success, diff --git a/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Chip.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Chip.kt index 106f0b839..9497bd92d 100644 --- a/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Chip.kt +++ b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Chip.kt @@ -73,6 +73,8 @@ fun NiaFilterChip( }, shape = CircleShape, border = FilterChipDefaults.filterChipBorder( + enabled = enabled, + selected = selected, borderColor = MaterialTheme.colorScheme.onBackground, selectedBorderColor = MaterialTheme.colorScheme.onBackground, disabledBorderColor = MaterialTheme.colorScheme.onBackground.copy( diff --git a/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/LoadingWheel.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/LoadingWheel.kt index 21dfbc8c3..ca168b4be 100644 --- a/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/LoadingWheel.kt +++ b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/LoadingWheel.kt @@ -96,8 +96,8 @@ fun NiaLoadingWheel( animationSpec = infiniteRepeatable( animation = keyframes { durationMillis = ROTATION_TIME / 2 - progressLineColor at ROTATION_TIME / NUM_OF_LINES / 2 with LinearEasing - baseLineColor at ROTATION_TIME / NUM_OF_LINES with LinearEasing + progressLineColor at ROTATION_TIME / NUM_OF_LINES / 2 using LinearEasing + baseLineColor at ROTATION_TIME / NUM_OF_LINES using LinearEasing }, repeatMode = RepeatMode.Restart, initialStartOffset = StartOffset(ROTATION_TIME / NUM_OF_LINES / 2 * index), diff --git a/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Tabs.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Tabs.kt index 92cd9aa8f..74753ca9b 100644 --- a/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Tabs.kt +++ b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Tabs.kt @@ -91,7 +91,7 @@ fun NiaTabRow( containerColor = Color.Transparent, contentColor = MaterialTheme.colorScheme.onSurface, indicator = { tabPositions -> - TabRowDefaults.Indicator( + TabRowDefaults.SecondaryIndicator( modifier = Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex]), height = 2.dp, color = MaterialTheme.colorScheme.onSurface, diff --git a/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/icon/NiaIcons.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/icon/NiaIcons.kt index 8db20689f..8d8a46424 100644 --- a/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/icon/NiaIcons.kt +++ b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/icon/NiaIcons.kt @@ -17,6 +17,7 @@ package com.google.samples.apps.nowinandroid.core.designsystem.icon import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.rounded.ArrowBack import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material.icons.outlined.Bookmarks import androidx.compose.material.icons.outlined.Upcoming @@ -31,7 +32,6 @@ import androidx.compose.material.icons.rounded.Grid3x3 import androidx.compose.material.icons.rounded.Person 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.Upcoming import androidx.compose.material.icons.rounded.ViewDay import androidx.compose.ui.graphics.vector.ImageVector @@ -41,7 +41,7 @@ import androidx.compose.ui.graphics.vector.ImageVector */ object NiaIcons { val Add = Icons.Rounded.Add - val ArrowBack = Icons.Rounded.ArrowBack + val ArrowBack = Icons.AutoMirrored.Rounded.ArrowBack val Bookmark = Icons.Rounded.Bookmark val BookmarkBorder = Icons.Rounded.BookmarkBorder val Bookmarks = Icons.Rounded.Bookmarks @@ -53,7 +53,7 @@ object NiaIcons { val Person = Icons.Rounded.Person val Search = Icons.Rounded.Search val Settings = Icons.Rounded.Settings - val ShortText = Icons.Rounded.ShortText + val ShortText = Icons.AutoMirrored.Rounded.ArrowBack val Upcoming = Icons.Rounded.Upcoming val UpcomingBorder = Icons.Outlined.Upcoming val ViewDay = Icons.Rounded.ViewDay diff --git a/feature/search/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt b/feature/search/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt index fc9c20549..6bbaf46d2 100644 --- a/feature/search/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt +++ b/feature/search/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt @@ -99,7 +99,7 @@ class SearchViewModelTest { searchContentsRepository.addNewsResources(newsResourcesTestData) searchContentsRepository.addTopics(topicsTestData) - val result = viewModel.searchResultUiState.value + // val result = viewModel.searchResultUiState.value // TODO: Figure out to get the latest emitted ui State? The result is emitted as EmptyQuery // assertIs(result) diff --git a/feature/settings/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsDialog.kt b/feature/settings/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsDialog.kt index 032515c53..db60a6447 100644 --- a/feature/settings/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsDialog.kt +++ b/feature/settings/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsDialog.kt @@ -37,7 +37,7 @@ import androidx.compose.foundation.selection.selectable import androidx.compose.foundation.selection.selectableGroup import androidx.compose.foundation.verticalScroll import androidx.compose.material3.AlertDialog -import androidx.compose.material3.Divider +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.RadioButton import androidx.compose.material3.Text @@ -115,7 +115,7 @@ fun SettingsDialog( ) }, text = { - Divider() + HorizontalDivider() Column(Modifier.verticalScroll(rememberScrollState())) { when (settingsUiState) { Loading -> { @@ -135,7 +135,7 @@ fun SettingsDialog( ) } } - Divider(Modifier.padding(top = 8.dp)) + HorizontalDivider(Modifier.padding(top = 8.dp)) LinksPanel() } TrackScreenViewEvent(screenName = "Settings") diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7e0380cab..eeee36003 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ androidTools = "31.2.0" androidxActivity = "1.8.0" androidxAppCompat = "1.6.1" androidxBrowser = "1.6.0" -androidxComposeBom = "2023.10.01" +androidxComposeBom = "2024.02.00" androidxComposeCompiler = "1.5.7" androidxComposeRuntimeTracing = "1.0.0-beta01" androidxCore = "1.12.0" From 6958a5ddcb23563844c9527a148e75f9267aa4b6 Mon Sep 17 00:00:00 2001 From: dturner Date: Mon, 19 Feb 2024 16:33:08 +0000 Subject: [PATCH 30/65] =?UTF-8?q?=F0=9F=A4=96=20Updates=20baselines=20for?= =?UTF-8?q?=20Dependency=20Guard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dependencies/releaseRuntimeClasspath.txt | 78 ++++++++--------- .../prodReleaseRuntimeClasspath.txt | 84 ++++++++++--------- 2 files changed, 83 insertions(+), 79 deletions(-) diff --git a/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt b/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt index c3f83d734..182ff5451 100644 --- a/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt +++ b/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt @@ -1,7 +1,7 @@ androidx.activity:activity-compose:1.8.0 androidx.activity:activity-ktx:1.8.0 androidx.activity:activity:1.8.0 -androidx.annotation:annotation-experimental:1.3.1 +androidx.annotation:annotation-experimental:1.4.0 androidx.annotation:annotation-jvm:1.7.0 androidx.annotation:annotation:1.7.0 androidx.appcompat:appcompat-resources:1.6.1 @@ -9,48 +9,50 @@ androidx.arch.core:core-common:2.2.0 androidx.arch.core:core-runtime:2.2.0 androidx.autofill:autofill:1.0.0 androidx.browser:browser:1.6.0 -androidx.collection:collection-jvm:1.3.0 -androidx.collection:collection:1.3.0 -androidx.compose.animation:animation-android:1.5.4 -androidx.compose.animation:animation-core-android:1.5.4 -androidx.compose.animation:animation-core:1.5.4 -androidx.compose.animation:animation:1.5.4 -androidx.compose.foundation:foundation-android:1.5.4 -androidx.compose.foundation:foundation-layout-android:1.5.4 -androidx.compose.foundation:foundation-layout:1.5.4 -androidx.compose.foundation:foundation:1.5.4 -androidx.compose.material3:material3:1.1.2 -androidx.compose.material:material-icons-core-android:1.5.4 -androidx.compose.material:material-icons-core:1.5.4 -androidx.compose.material:material-icons-extended-android:1.5.4 -androidx.compose.material:material-icons-extended:1.5.4 -androidx.compose.material:material-ripple-android:1.5.4 -androidx.compose.material:material-ripple:1.5.4 -androidx.compose.runtime:runtime-android:1.5.4 -androidx.compose.runtime:runtime-saveable-android:1.5.4 -androidx.compose.runtime:runtime-saveable:1.5.4 -androidx.compose.runtime:runtime:1.5.4 -androidx.compose.ui:ui-android:1.5.4 -androidx.compose.ui:ui-geometry-android:1.5.4 -androidx.compose.ui:ui-geometry:1.5.4 -androidx.compose.ui:ui-graphics-android:1.5.4 -androidx.compose.ui:ui-graphics:1.5.4 -androidx.compose.ui:ui-text-android:1.5.4 -androidx.compose.ui:ui-text:1.5.4 -androidx.compose.ui:ui-tooling-preview-android:1.5.4 -androidx.compose.ui:ui-tooling-preview:1.5.4 -androidx.compose.ui:ui-unit-android:1.5.4 -androidx.compose.ui:ui-unit:1.5.4 -androidx.compose.ui:ui-util-android:1.5.4 -androidx.compose.ui:ui-util:1.5.4 -androidx.compose.ui:ui:1.5.4 -androidx.compose:compose-bom:2023.10.01 +androidx.collection:collection-jvm:1.4.0 +androidx.collection:collection-ktx:1.4.0 +androidx.collection:collection:1.4.0 +androidx.compose.animation:animation-android:1.6.1 +androidx.compose.animation:animation-core-android:1.6.1 +androidx.compose.animation:animation-core:1.6.1 +androidx.compose.animation:animation:1.6.1 +androidx.compose.foundation:foundation-android:1.6.1 +androidx.compose.foundation:foundation-layout-android:1.6.1 +androidx.compose.foundation:foundation-layout:1.6.1 +androidx.compose.foundation:foundation:1.6.1 +androidx.compose.material3:material3-android:1.2.0 +androidx.compose.material3:material3:1.2.0 +androidx.compose.material:material-icons-core-android:1.6.1 +androidx.compose.material:material-icons-core:1.6.1 +androidx.compose.material:material-icons-extended-android:1.6.1 +androidx.compose.material:material-icons-extended:1.6.1 +androidx.compose.material:material-ripple-android:1.6.1 +androidx.compose.material:material-ripple:1.6.1 +androidx.compose.runtime:runtime-android:1.6.1 +androidx.compose.runtime:runtime-saveable-android:1.6.1 +androidx.compose.runtime:runtime-saveable:1.6.1 +androidx.compose.runtime:runtime:1.6.1 +androidx.compose.ui:ui-android:1.6.1 +androidx.compose.ui:ui-geometry-android:1.6.1 +androidx.compose.ui:ui-geometry:1.6.1 +androidx.compose.ui:ui-graphics-android:1.6.1 +androidx.compose.ui:ui-graphics:1.6.1 +androidx.compose.ui:ui-text-android:1.6.1 +androidx.compose.ui:ui-text:1.6.1 +androidx.compose.ui:ui-tooling-preview-android:1.6.1 +androidx.compose.ui:ui-tooling-preview:1.6.1 +androidx.compose.ui:ui-unit-android:1.6.1 +androidx.compose.ui:ui-unit:1.6.1 +androidx.compose.ui:ui-util-android:1.6.1 +androidx.compose.ui:ui-util:1.6.1 +androidx.compose.ui:ui:1.6.1 +androidx.compose:compose-bom:2024.02.00 androidx.concurrent:concurrent-futures:1.1.0 androidx.core:core-ktx:1.12.0 androidx.core:core:1.12.0 androidx.customview:customview-poolingcontainer:1.0.0 androidx.customview:customview:1.0.0 -androidx.emoji2:emoji2:1.4.0 +androidx.emoji2:emoji2:1.3.0 androidx.exifinterface:exifinterface:1.3.6 androidx.fragment:fragment:1.5.1 androidx.interpolator:interpolator:1.0.0 diff --git a/app/dependencies/prodReleaseRuntimeClasspath.txt b/app/dependencies/prodReleaseRuntimeClasspath.txt index eaeff771a..e7a4ac804 100644 --- a/app/dependencies/prodReleaseRuntimeClasspath.txt +++ b/app/dependencies/prodReleaseRuntimeClasspath.txt @@ -1,7 +1,7 @@ androidx.activity:activity-compose:1.8.0 androidx.activity:activity-ktx:1.8.0 androidx.activity:activity:1.8.0 -androidx.annotation:annotation-experimental:1.3.1 +androidx.annotation:annotation-experimental:1.4.0 androidx.annotation:annotation-jvm:1.7.0 androidx.annotation:annotation:1.7.0 androidx.appcompat:appcompat-resources:1.6.1 @@ -10,44 +10,46 @@ androidx.arch.core:core-common:2.2.0 androidx.arch.core:core-runtime:2.2.0 androidx.autofill:autofill:1.0.0 androidx.browser:browser:1.6.0 -androidx.collection:collection-jvm:1.3.0 -androidx.collection:collection-ktx:1.3.0 -androidx.collection:collection:1.3.0 -androidx.compose.animation:animation-android:1.5.4 -androidx.compose.animation:animation-core-android:1.5.4 -androidx.compose.animation:animation-core:1.5.4 -androidx.compose.animation:animation:1.5.4 -androidx.compose.foundation:foundation-android:1.5.4 -androidx.compose.foundation:foundation-layout-android:1.5.4 -androidx.compose.foundation:foundation-layout:1.5.4 -androidx.compose.foundation:foundation:1.5.4 -androidx.compose.material3:material3-window-size-class:1.1.2 -androidx.compose.material3:material3:1.1.2 -androidx.compose.material:material-icons-core-android:1.5.4 -androidx.compose.material:material-icons-core:1.5.4 -androidx.compose.material:material-icons-extended-android:1.5.4 -androidx.compose.material:material-icons-extended:1.5.4 -androidx.compose.material:material-ripple-android:1.5.4 -androidx.compose.material:material-ripple:1.5.4 -androidx.compose.runtime:runtime-android:1.5.4 -androidx.compose.runtime:runtime-saveable-android:1.5.4 -androidx.compose.runtime:runtime-saveable:1.5.4 -androidx.compose.runtime:runtime:1.5.4 -androidx.compose.ui:ui-android:1.5.4 -androidx.compose.ui:ui-geometry-android:1.5.4 -androidx.compose.ui:ui-geometry:1.5.4 -androidx.compose.ui:ui-graphics-android:1.5.4 -androidx.compose.ui:ui-graphics:1.5.4 -androidx.compose.ui:ui-text-android:1.5.4 -androidx.compose.ui:ui-text:1.5.4 -androidx.compose.ui:ui-tooling-preview-android:1.5.4 -androidx.compose.ui:ui-tooling-preview:1.5.4 -androidx.compose.ui:ui-unit-android:1.5.4 -androidx.compose.ui:ui-unit:1.5.4 -androidx.compose.ui:ui-util-android:1.5.4 -androidx.compose.ui:ui-util:1.5.4 -androidx.compose.ui:ui:1.5.4 -androidx.compose:compose-bom:2023.10.01 +androidx.collection:collection-jvm:1.4.0 +androidx.collection:collection-ktx:1.4.0 +androidx.collection:collection:1.4.0 +androidx.compose.animation:animation-android:1.6.1 +androidx.compose.animation:animation-core-android:1.6.1 +androidx.compose.animation:animation-core:1.6.1 +androidx.compose.animation:animation:1.6.1 +androidx.compose.foundation:foundation-android:1.6.1 +androidx.compose.foundation:foundation-layout-android:1.6.1 +androidx.compose.foundation:foundation-layout:1.6.1 +androidx.compose.foundation:foundation:1.6.1 +androidx.compose.material3:material3-android:1.2.0 +androidx.compose.material3:material3-window-size-class-android:1.2.0 +androidx.compose.material3:material3-window-size-class:1.2.0 +androidx.compose.material3:material3:1.2.0 +androidx.compose.material:material-icons-core-android:1.6.1 +androidx.compose.material:material-icons-core:1.6.1 +androidx.compose.material:material-icons-extended-android:1.6.1 +androidx.compose.material:material-icons-extended:1.6.1 +androidx.compose.material:material-ripple-android:1.6.1 +androidx.compose.material:material-ripple:1.6.1 +androidx.compose.runtime:runtime-android:1.6.1 +androidx.compose.runtime:runtime-saveable-android:1.6.1 +androidx.compose.runtime:runtime-saveable:1.6.1 +androidx.compose.runtime:runtime:1.6.1 +androidx.compose.ui:ui-android:1.6.1 +androidx.compose.ui:ui-geometry-android:1.6.1 +androidx.compose.ui:ui-geometry:1.6.1 +androidx.compose.ui:ui-graphics-android:1.6.1 +androidx.compose.ui:ui-graphics:1.6.1 +androidx.compose.ui:ui-text-android:1.6.1 +androidx.compose.ui:ui-text:1.6.1 +androidx.compose.ui:ui-tooling-preview-android:1.6.1 +androidx.compose.ui:ui-tooling-preview:1.6.1 +androidx.compose.ui:ui-unit-android:1.6.1 +androidx.compose.ui:ui-unit:1.6.1 +androidx.compose.ui:ui-util-android:1.6.1 +androidx.compose.ui:ui-util:1.6.1 +androidx.compose.ui:ui:1.6.1 +androidx.compose:compose-bom:2024.02.00 androidx.concurrent:concurrent-futures:1.1.0 androidx.core:core-ktx:1.12.0 androidx.core:core-splashscreen:1.0.1 @@ -61,8 +63,8 @@ androidx.datastore:datastore-preferences:1.0.0 androidx.datastore:datastore:1.0.0 androidx.documentfile:documentfile:1.0.0 androidx.drawerlayout:drawerlayout:1.0.0 -androidx.emoji2:emoji2-views-helper:1.4.0 -androidx.emoji2:emoji2:1.4.0 +androidx.emoji2:emoji2-views-helper:1.3.0 +androidx.emoji2:emoji2:1.3.0 androidx.exifinterface:exifinterface:1.3.6 androidx.fragment:fragment:1.5.1 androidx.hilt:hilt-common:1.1.0 From 4a1015287d7b06e5d119ae9b9b6df4b5b78f4a4b Mon Sep 17 00:00:00 2001 From: dturner Date: Mon, 19 Feb 2024 16:37:09 +0000 Subject: [PATCH 31/65] =?UTF-8?q?=F0=9F=A4=96=20Updates=20screenshots?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Width_compactHeight_showsNavigationBar.png | Bin 37230 -> 37104 bytes ...idth_expandedHeight_showsNavigationBar.png | Bin 107363 -> 107675 bytes ...tWidth_mediumHeight_showsNavigationBar.png | Bin 52205 -> 51810 bytes ...idth_compactHeight_showsNavigationRail.png | Bin 77374 -> 77002 bytes ...dth_expandedHeight_showsNavigationRail.png | Bin 239019 -> 237134 bytes ...Width_mediumHeight_showsNavigationRail.png | Bin 114836 -> 113816 bytes ...idth_compactHeight_showsNavigationRail.png | Bin 59215 -> 58987 bytes ...dth_expandedHeight_showsNavigationRail.png | Bin 156220 -> 153617 bytes ...Width_mediumHeight_showsNavigationRail.png | Bin 84728 -> 83940 bytes .../Background_dark_defaultTheme_dynamic.png | Bin 5761 -> 5609 bytes ...ackground_dark_defaultTheme_notDynamic.png | Bin 4471 -> 4323 bytes ...ckground_light_androidTheme_notDynamic.png | Bin 4915 -> 4801 bytes .../Background_light_defaultTheme_dynamic.png | Bin 5614 -> 5479 bytes ...ckground_light_defaultTheme_notDynamic.png | Bin 4252 -> 4131 bytes ...ntBackground_dark_defaultTheme_dynamic.png | Bin 4447 -> 4182 bytes ...ackground_dark_defaultTheme_notDynamic.png | Bin 11158 -> 10908 bytes ...ckground_light_androidTheme_notDynamic.png | Bin 4915 -> 4801 bytes ...tBackground_light_defaultTheme_dynamic.png | Bin 5720 -> 5595 bytes ...ckground_light_defaultTheme_notDynamic.png | Bin 10857 -> 10609 bytes ...nLeadingIcon_dark_defaultTheme_dynamic.png | Bin 4777 -> 4701 bytes ...adingIcon_dark_defaultTheme_notDynamic.png | Bin 3807 -> 3741 bytes ...LeadingIcon_light_defaultTheme_dynamic.png | Bin 4774 -> 4596 bytes ...dingIcon_light_defaultTheme_notDynamic.png | Bin 3396 -> 3351 bytes .../Button_dark_androidTheme_notDynamic.png | Bin 4266 -> 4188 bytes .../Button_dark_defaultTheme_dynamic.png | Bin 4981 -> 4886 bytes .../Button_dark_defaultTheme_notDynamic.png | Bin 3899 -> 3831 bytes .../Button_light_androidTheme_notDynamic.png | Bin 3887 -> 3849 bytes .../Button_light_defaultTheme_dynamic.png | Bin 5099 -> 4896 bytes .../Button_light_defaultTheme_notDynamic.png | Bin 3999 -> 3917 bytes ...ineButton_dark_androidTheme_notDynamic.png | Bin 5651 -> 5623 bytes ...utlineButton_dark_defaultTheme_dynamic.png | Bin 6436 -> 6337 bytes ...ineButton_dark_defaultTheme_notDynamic.png | Bin 5247 -> 5200 bytes ...neButton_light_androidTheme_notDynamic.png | Bin 5393 -> 5382 bytes ...tlineButton_light_defaultTheme_dynamic.png | Bin 6381 -> 6266 bytes ...neButton_light_defaultTheme_notDynamic.png | Bin 5483 -> 5389 bytes ...pSelected_dark_androidTheme_notDynamic.png | Bin 3265 -> 3284 bytes ...ChipSelected_dark_defaultTheme_dynamic.png | Bin 3246 -> 3211 bytes ...pSelected_dark_defaultTheme_notDynamic.png | Bin 3190 -> 3200 bytes ...Selected_light_androidTheme_notDynamic.png | Bin 3247 -> 3260 bytes ...hipSelected_light_defaultTheme_dynamic.png | Bin 3249 -> 3300 bytes ...Selected_light_defaultTheme_notDynamic.png | Bin 3231 -> 3251 bytes ...ilterChip_dark_androidTheme_notDynamic.png | Bin 2936 -> 2965 bytes .../FilterChip_dark_defaultTheme_dynamic.png | Bin 2889 -> 2975 bytes ...ilterChip_dark_defaultTheme_notDynamic.png | Bin 2922 -> 2954 bytes .../FilterChip/FilterChip_fontScale2.png | Bin 2824 -> 2797 bytes ...lterChip_light_androidTheme_notDynamic.png | Bin 2950 -> 2974 bytes .../FilterChip_light_defaultTheme_dynamic.png | Bin 2992 -> 2925 bytes ...lterChip_light_defaultTheme_notDynamic.png | Bin 2956 -> 2992 bytes ...tonUnchecked_dark_defaultTheme_dynamic.png | Bin 1288 -> 1270 bytes ...onUnchecked_light_defaultTheme_dynamic.png | Bin 1159 -> 1097 bytes ...LoadingWheel_dark_defaultTheme_dynamic.png | Bin 1046 -> 1061 bytes ...oadingWheel_light_defaultTheme_dynamic.png | Bin 1134 -> 1036 bytes ...LoadingWheel_dark_defaultTheme_dynamic.png | Bin 1888 -> 1829 bytes ...oadingWheel_light_defaultTheme_dynamic.png | Bin 1831 -> 1710 bytes ...avigation_dark_androidTheme_notDynamic.png | Bin 3832 -> 3832 bytes .../Navigation_dark_defaultTheme_dynamic.png | Bin 3906 -> 3884 bytes ...avigation_dark_defaultTheme_notDynamic.png | Bin 3859 -> 3859 bytes .../Navigation/Navigation_fontScale2.png | Bin 7799 -> 8199 bytes ...vigation_light_androidTheme_notDynamic.png | Bin 3931 -> 3931 bytes .../Navigation_light_defaultTheme_dynamic.png | Bin 3807 -> 3772 bytes ...vigation_light_defaultTheme_notDynamic.png | Bin 3731 -> 3731 bytes .../Tabs_dark_androidTheme_notDynamic.png | Bin 2806 -> 2813 bytes .../Tabs/Tabs_dark_defaultTheme_dynamic.png | Bin 2799 -> 2808 bytes .../Tabs_dark_defaultTheme_notDynamic.png | Bin 2797 -> 2828 bytes .../test/screenshots/Tabs/Tabs_fontScale2.png | Bin 7379 -> 6823 bytes .../Tabs_light_androidTheme_notDynamic.png | Bin 2792 -> 2860 bytes .../Tabs/Tabs_light_defaultTheme_dynamic.png | Bin 2849 -> 2809 bytes .../Tabs_light_defaultTheme_notDynamic.png | Bin 2822 -> 2836 bytes .../Tag/Tag_dark_androidTheme_notDynamic.png | Bin 1885 -> 1885 bytes .../Tag/Tag_dark_defaultTheme_dynamic.png | Bin 1868 -> 1869 bytes .../Tag/Tag_dark_defaultTheme_notDynamic.png | Bin 1828 -> 1828 bytes .../test/screenshots/Tag/Tag_fontScale2.png | Bin 4178 -> 4229 bytes .../Tag/Tag_light_androidTheme_notDynamic.png | Bin 1846 -> 1847 bytes .../Tag/Tag_light_defaultTheme_dynamic.png | Bin 1714 -> 1701 bytes .../Tag/Tag_light_defaultTheme_notDynamic.png | Bin 1730 -> 1722 bytes ...TopAppBar_dark_androidTheme_notDynamic.png | Bin 3406 -> 3405 bytes .../TopAppBar_dark_defaultTheme_dynamic.png | Bin 3387 -> 3468 bytes ...TopAppBar_dark_defaultTheme_notDynamic.png | Bin 3398 -> 3394 bytes .../TopAppBar/TopAppBar_fontScale2.png | Bin 5571 -> 4898 bytes ...opAppBar_light_androidTheme_notDynamic.png | Bin 3430 -> 3425 bytes .../TopAppBar_light_defaultTheme_dynamic.png | Bin 3417 -> 3365 bytes ...opAppBar_light_defaultTheme_notDynamic.png | Bin 3453 -> 3449 bytes ...rYouScreenPopulatedAndLoading_foldable.png | Bin 196181 -> 200640 bytes .../ForYouScreenPopulatedAndLoading_phone.png | Bin 40531 -> 40984 bytes ...ouScreenPopulatedAndLoading_phone_dark.png | Bin 40897 -> 41363 bytes ...ForYouScreenPopulatedAndLoading_tablet.png | Bin 226158 -> 231429 bytes .../ForYouScreenPopulatedFeed_foldable.png | Bin 192148 -> 196599 bytes .../ForYouScreenPopulatedFeed_phone.png | Bin 37456 -> 37948 bytes .../ForYouScreenPopulatedFeed_tablet.png | Bin 221631 -> 226980 bytes .../ForYouScreenTopicSelection_foldable.png | Bin 90349 -> 94706 bytes .../ForYouScreenTopicSelection_phone.png | Bin 23119 -> 23126 bytes .../ForYouScreenTopicSelection_phone_dark.png | Bin 24125 -> 24118 bytes .../ForYouScreenTopicSelection_tablet.png | Bin 96315 -> 101125 bytes 93 files changed, 0 insertions(+), 0 deletions(-) diff --git a/app/src/testDemo/screenshots/compactWidth_compactHeight_showsNavigationBar.png b/app/src/testDemo/screenshots/compactWidth_compactHeight_showsNavigationBar.png index 04ccb84241de8e88a085ef654b0540cc2e536145..6f3e9196172e9921a6fca779a17662384efad7a1 100644 GIT binary patch literal 37104 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≧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 literal 37230 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 z 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 diff --git a/app/src/testDemo/screenshots/compactWidth_expandedHeight_showsNavigationBar.png b/app/src/testDemo/screenshots/compactWidth_expandedHeight_showsNavigationBar.png index 833ecdf07d171612cdea78a92c84305ff8f69221..01d1d46c0ef2a9ec7583cc3d1f5f7524ff1b3ae1 100644 GIT binary patch literal 107675 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%0DgvC8%Hs1X@o%+OYIdJ_Bi-yQqg+9w#U~o)I3n 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 VY&>%Ss+5lIfwsO@*Eg`xyWL literal 107363 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