diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md deleted file mode 100644 index c38247d232..0000000000 --- a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -name: Pull request -about: Create a pull request -label: 'triage me' ---- -Thank you for opening a Pull Request! -Before submitting your PR, there are a few things you can do to make sure it goes smoothly: -- [ ] Make sure to open a GitHub issue as a bug/feature request before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea -- [ ] Ensure the tests and linter pass (`./gradlew --init-script gradle/init.gradle.kts spotlessApply` to automatically apply formatting) -- [ ] Appropriate docs were updated (if necessary) - -Is this your first Pull Request? -- [ ] Run `./tools/setup.sh` -- [ ] Import the code formatting style as explained in [the setup script](/tools/setup.sh#L40). - -Fixes # 🦕 diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000000..ed5fa237d2 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,17 @@ +Thanks for submitting a pull request. Please include the following information. + +**What I have done and why** +Include a summary of what your pull request contains, and why you have made these changes. + +Fixes # + +**Do tests pass?** +- [ ] Run local tests on `DemoDebug` variant: `./gradlew testDemoDebug` +- [ ] Check formatting: `./gradlew --init-script gradle/init.gradle.kts spotlessApply` + +**Is this your first pull request?** +- [ ] [Sign the CLA](https://cla.developers.google.com/) +- [ ] Run `./tools/setup.sh` +- [ ] Import the code formatting style as explained in [the setup script](/tools/setup.sh#L40). + + diff --git a/.github/workflows/Build.yaml b/.github/workflows/Build.yaml index 9a0dca1060..ccea5dc4f5 100644 --- a/.github/workflows/Build.yaml +++ b/.github/workflows/Build.yaml @@ -17,7 +17,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Validate Gradle Wrapper uses: gradle/wrapper-validation-action@v1 @@ -47,7 +47,7 @@ jobs: path: '**/build/outputs/apk/**/*.apk' - name: Run local tests - run: ./gradlew testDemoDebug testProdDebug + run: ./gradlew testDemoDebug testProdDebug :lint:test test: runs-on: ubuntu-latest @@ -59,7 +59,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Validate Gradle Wrapper uses: gradle/wrapper-validation-action@v1 @@ -96,7 +96,7 @@ jobs: ./gradlew recordRoborazziDemoDebug - name: Push new screenshots if available - uses: stefanzweifel/git-auto-commit-action@v4 + uses: stefanzweifel/git-auto-commit-action@v5 if: steps.screenshotsrecord.outcome == 'success' with: file_pattern: '*/*.png' @@ -125,6 +125,9 @@ jobs: name: lint-reports path: '**/build/reports/lint-results-*.html' + - name: Check badging + run: ./gradlew :app:checkProdReleaseBadging + androidTest: needs: build runs-on: macOS-latest # enables hardware acceleration in the virtual machine @@ -135,7 +138,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Copy CI gradle.properties run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties @@ -168,45 +171,3 @@ jobs: with: name: test-reports-${{ matrix.api-level }} path: '**/build/reports/androidTests' - - androidTest-GMD: - needs: build - runs-on: macOS-latest # enables hardware acceleration in the virtual machine - timeout-minutes: 90 - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Copy CI gradle.properties - run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties - - - name: Set up JDK 17 - uses: actions/setup-java@v3 - with: - distribution: 'zulu' - java-version: 17 - - - name: Setup Gradle - uses: gradle/gradle-build-action@v2 - - - name: Accept Android licenses - run: yes | "$ANDROID_HOME"/cmdline-tools/latest/bin/sdkmanager --licenses || true - - - name: Build AndroidTest apps - run: ./gradlew packageDemoDebug packageDemoDebugAndroidTest - - - name: Run instrumented tests with GMD - run: ./gradlew ciDemoDebugAndroidTest --no-parallel --max-workers=1 - -Pandroid.testoptions.manageddevices.emulator.gpu="swiftshader_indirect" -Pandroid.experimental.testOptions.managedDevices.emulator.showKernelLogging=true - - - name: Upload test reports - if: success() || failure() - uses: actions/upload-artifact@v3 - with: - name: test-reports-GMD - path: '**/build/reports/androidTests' - - - name: Print disk space usage - if: failure() - run: df -h diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml index 534e9d8934..96285d10ec 100644 --- a/.github/workflows/Release.yml +++ b/.github/workflows/Release.yml @@ -12,7 +12,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Validate Gradle Wrapper uses: gradle/wrapper-validation-action@v1 diff --git a/.idea/copyright/The_Android_Open_Source_Project.xml b/.idea/copyright/The_Android_Open_Source_Project.xml index 74acd98d85..855f041e8f 100644 --- a/.idea/copyright/The_Android_Open_Source_Project.xml +++ b/.idea/copyright/The_Android_Open_Source_Project.xml @@ -1,6 +1,6 @@ - - \ No newline at end of file + diff --git a/app-nia-catalog/build.gradle.kts b/app-nia-catalog/build.gradle.kts index 1f9ac1e2a5..a90da1604d 100644 --- a/app-nia-catalog/build.gradle.kts +++ b/app-nia-catalog/build.gradle.kts @@ -32,8 +32,8 @@ import com.google.samples.apps.nowinandroid.NiaFlavor * limitations under the License. */ plugins { - id("nowinandroid.android.application") - id("nowinandroid.android.application.compose") + alias(libs.plugins.nowinandroid.android.application) + alias(libs.plugins.nowinandroid.android.application.compose) } android { @@ -65,7 +65,7 @@ android { } dependencies { - implementation(project(":core:designsystem")) - implementation(project(":core:ui")) + implementation(projects.core.designsystem) + implementation(projects.core.ui) implementation(libs.androidx.activity.compose) } diff --git a/app-nia-catalog/src/main/java/com/google/samples/apps/niacatalog/NiaCatalogActivity.kt b/app-nia-catalog/src/main/kotlin/com/google/samples/apps/niacatalog/NiaCatalogActivity.kt similarity index 100% rename from app-nia-catalog/src/main/java/com/google/samples/apps/niacatalog/NiaCatalogActivity.kt rename to app-nia-catalog/src/main/kotlin/com/google/samples/apps/niacatalog/NiaCatalogActivity.kt diff --git a/app-nia-catalog/src/main/java/com/google/samples/apps/niacatalog/ui/Catalog.kt b/app-nia-catalog/src/main/kotlin/com/google/samples/apps/niacatalog/ui/Catalog.kt similarity index 95% rename from app-nia-catalog/src/main/java/com/google/samples/apps/niacatalog/ui/Catalog.kt rename to app-nia-catalog/src/main/kotlin/com/google/samples/apps/niacatalog/ui/Catalog.kt index 2624262ad0..02d4cf8d53 100644 --- a/app-nia-catalog/src/main/java/com/google/samples/apps/niacatalog/ui/Catalog.kt +++ b/app-nia-catalog/src/main/kotlin/com/google/samples/apps/niacatalog/ui/Catalog.kt @@ -32,8 +32,9 @@ import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp @@ -170,13 +171,13 @@ fun NiaCatalog() { item { Text("Chips", Modifier.padding(top = 16.dp)) } item { FlowRow(horizontalArrangement = Arrangement.spacedBy(16.dp)) { - var firstChecked by remember { mutableStateOf(false) } + var firstChecked by rememberSaveable { mutableStateOf(false) } NiaFilterChip( selected = firstChecked, onSelectedChange = { checked -> firstChecked = checked }, label = { Text(text = "Enabled") }, ) - var secondChecked by remember { mutableStateOf(true) } + var secondChecked by rememberSaveable { mutableStateOf(true) } NiaFilterChip( selected = secondChecked, onSelectedChange = { checked -> secondChecked = checked }, @@ -199,7 +200,7 @@ fun NiaCatalog() { item { Text("Icon buttons", Modifier.padding(top = 16.dp)) } item { FlowRow(horizontalArrangement = Arrangement.spacedBy(16.dp)) { - var firstChecked by remember { mutableStateOf(false) } + var firstChecked by rememberSaveable { mutableStateOf(false) } NiaIconToggleButton( checked = firstChecked, onCheckedChange = { checked -> firstChecked = checked }, @@ -216,7 +217,7 @@ fun NiaCatalog() { ) }, ) - var secondChecked by remember { mutableStateOf(true) } + var secondChecked by rememberSaveable { mutableStateOf(true) } NiaIconToggleButton( checked = secondChecked, onCheckedChange = { checked -> secondChecked = checked }, @@ -272,14 +273,14 @@ fun NiaCatalog() { item { Text("View toggle", Modifier.padding(top = 16.dp)) } item { FlowRow(horizontalArrangement = Arrangement.spacedBy(16.dp)) { - var firstExpanded by remember { mutableStateOf(false) } + var firstExpanded by rememberSaveable { mutableStateOf(false) } NiaViewToggleButton( expanded = firstExpanded, onExpandedChange = { expanded -> firstExpanded = expanded }, compactText = { Text(text = "Compact view") }, expandedText = { Text(text = "Expanded view") }, ) - var secondExpanded by remember { mutableStateOf(true) } + var secondExpanded by rememberSaveable { mutableStateOf(true) } NiaViewToggleButton( expanded = secondExpanded, onExpandedChange = { expanded -> secondExpanded = expanded }, @@ -318,7 +319,7 @@ fun NiaCatalog() { } item { Text("Tabs", Modifier.padding(top = 16.dp)) } item { - var selectedTabIndex by remember { mutableStateOf(0) } + var selectedTabIndex by rememberSaveable { mutableIntStateOf(0) } val titles = listOf("Topics", "People") NiaTabRow(selectedTabIndex = selectedTabIndex) { titles.forEachIndexed { index, title -> @@ -332,7 +333,7 @@ fun NiaCatalog() { } item { Text("Navigation", Modifier.padding(top = 16.dp)) } item { - var selectedItem by remember { mutableStateOf(0) } + var selectedItem by rememberSaveable { mutableIntStateOf(0) } val items = listOf("For you", "Saved", "Interests") val icons = listOf( NiaIcons.UpcomingBorder, diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a15085a406..7947d17822 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -16,13 +16,13 @@ import com.google.samples.apps.nowinandroid.NiaBuildType plugins { - id("nowinandroid.android.application") - id("nowinandroid.android.application.compose") - id("nowinandroid.android.application.flavors") - id("nowinandroid.android.application.jacoco") - id("nowinandroid.android.hilt") + alias(libs.plugins.nowinandroid.android.application) + alias(libs.plugins.nowinandroid.android.application.compose) + alias(libs.plugins.nowinandroid.android.application.flavors) + alias(libs.plugins.nowinandroid.android.application.jacoco) + alias(libs.plugins.nowinandroid.android.hilt) id("jacoco") - id("nowinandroid.android.application.firebase") + alias(libs.plugins.nowinandroid.android.application.firebase) id("com.google.android.gms.oss-licenses-plugin") } @@ -80,31 +80,31 @@ android { } dependencies { - implementation(project(":feature:interests")) - implementation(project(":feature:foryou")) - implementation(project(":feature:bookmarks")) - implementation(project(":feature:topic")) - implementation(project(":feature:search")) - implementation(project(":feature:settings")) + implementation(projects.feature.interests) + implementation(projects.feature.foryou) + implementation(projects.feature.bookmarks) + implementation(projects.feature.topic) + implementation(projects.feature.search) + implementation(projects.feature.settings) - implementation(project(":core:common")) - implementation(project(":core:ui")) - implementation(project(":core:designsystem")) - implementation(project(":core:data")) - implementation(project(":core:model")) - implementation(project(":core:analytics")) + implementation(projects.core.common) + implementation(projects.core.ui) + implementation(projects.core.designsystem) + implementation(projects.core.data) + implementation(projects.core.model) + implementation(projects.core.analytics) - implementation(project(":sync:work")) + implementation(projects.sync.work) - androidTestImplementation(project(":core:testing")) - androidTestImplementation(project(":core:datastore-test")) - androidTestImplementation(project(":core:data-test")) - androidTestImplementation(project(":core:network")) + androidTestImplementation(projects.core.testing) + androidTestImplementation(projects.core.datastoreTest) + androidTestImplementation(projects.core.dataTest) + androidTestImplementation(projects.core.network) androidTestImplementation(libs.androidx.navigation.testing) androidTestImplementation(libs.accompanist.testharness) androidTestImplementation(kotlin("test")) debugImplementation(libs.androidx.compose.ui.testManifest) - debugImplementation(project(":ui-test-hilt-manifest")) + debugImplementation(projects.uiTestHiltManifest) implementation(libs.androidx.activity.compose) implementation(libs.androidx.appcompat) @@ -122,12 +122,13 @@ dependencies { implementation(libs.coil.kt) // Core functions - testImplementation(project(":core:testing")) - testImplementation(project(":core:datastore-test")) - testImplementation(project(":core:data-test")) - testImplementation(project(":core:network")) + testImplementation(projects.core.testing) + testImplementation(projects.core.datastoreTest) + testImplementation(projects.core.dataTest) + testImplementation(projects.core.network) testImplementation(libs.androidx.navigation.testing) testImplementation(libs.accompanist.testharness) + testImplementation(libs.work.testing) testImplementation(kotlin("test")) implementation(libs.work.testing) kspTest(libs.hilt.compiler) diff --git a/app/prodRelease-badging.txt b/app/prodRelease-badging.txt new file mode 100644 index 0000000000..6c3a859c7c --- /dev/null +++ b/app/prodRelease-badging.txt @@ -0,0 +1,121 @@ +package: name='com.google.samples.apps.nowinandroid' versionCode='8' versionName='0.1.2' platformBuildVersionName='14' platformBuildVersionCode='34' compileSdkVersion='34' compileSdkVersionCodename='14' +sdkVersion:'21' +targetSdkVersion:'34' +uses-permission: name='android.permission.INTERNET' +uses-permission: name='android.permission.ACCESS_NETWORK_STATE' +uses-permission: name='android.permission.POST_NOTIFICATIONS' +uses-permission: name='android.permission.WAKE_LOCK' +uses-permission: name='com.google.android.c2dm.permission.RECEIVE' +uses-permission: name='com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE' +uses-permission: name='android.permission.RECEIVE_BOOT_COMPLETED' +uses-permission: name='android.permission.FOREGROUND_SERVICE' +uses-permission: name='com.google.samples.apps.nowinandroid.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION' +application-label:'Now in Android' +application-label-af:'Now in Android' +application-label-am:'Now in Android' +application-label-ar:'Now in Android' +application-label-as:'Now in Android' +application-label-az:'Now in Android' +application-label-be:'Now in Android' +application-label-bg:'Now in Android' +application-label-bn:'Now in Android' +application-label-bs:'Now in Android' +application-label-ca:'Now in Android' +application-label-cs:'Now in Android' +application-label-da:'Now in Android' +application-label-de:'Now in Android' +application-label-el:'Now in Android' +application-label-en-AU:'Now in Android' +application-label-en-CA:'Now in Android' +application-label-en-GB:'Now in Android' +application-label-en-IN:'Now in Android' +application-label-en-XC:'Now in Android' +application-label-es:'Now in Android' +application-label-es-US:'Now in Android' +application-label-et:'Now in Android' +application-label-eu:'Now in Android' +application-label-fa:'Now in Android' +application-label-fi:'Now in Android' +application-label-fr:'Now in Android' +application-label-fr-CA:'Now in Android' +application-label-gl:'Now in Android' +application-label-gu:'Now in Android' +application-label-hi:'Now in Android' +application-label-hr:'Now in Android' +application-label-hu:'Now in Android' +application-label-hy:'Now in Android' +application-label-in:'Now in Android' +application-label-is:'Now in Android' +application-label-it:'Now in Android' +application-label-iw:'Now in Android' +application-label-ja:'Now in Android' +application-label-ka:'Now in Android' +application-label-kk:'Now in Android' +application-label-km:'Now in Android' +application-label-kn:'Now in Android' +application-label-ko:'Now in Android' +application-label-ky:'Now in Android' +application-label-lo:'Now in Android' +application-label-lt:'Now in Android' +application-label-lv:'Now in Android' +application-label-mk:'Now in Android' +application-label-ml:'Now in Android' +application-label-mn:'Now in Android' +application-label-mr:'Now in Android' +application-label-ms:'Now in Android' +application-label-my:'Now in Android' +application-label-nb:'Now in Android' +application-label-ne:'Now in Android' +application-label-nl:'Now in Android' +application-label-or:'Now in Android' +application-label-pa:'Now in Android' +application-label-pl:'Now in Android' +application-label-pt:'Now in Android' +application-label-pt-BR:'Now in Android' +application-label-pt-PT:'Now in Android' +application-label-ro:'Now in Android' +application-label-ru:'Now in Android' +application-label-si:'Now in Android' +application-label-sk:'Now in Android' +application-label-sl:'Now in Android' +application-label-sq:'Now in Android' +application-label-sr:'Now in Android' +application-label-sr-Latn:'Now in Android' +application-label-sv:'Now in Android' +application-label-sw:'Now in Android' +application-label-ta:'Now in Android' +application-label-te:'Now in Android' +application-label-th:'Now in Android' +application-label-tl:'Now in Android' +application-label-tr:'Now in Android' +application-label-uk:'Now in Android' +application-label-ur:'Now in Android' +application-label-uz:'Now in Android' +application-label-vi:'Now in Android' +application-label-zh-CN:'Now in Android' +application-label-zh-HK:'Now in Android' +application-label-zh-TW:'Now in Android' +application-label-zu:'Now in Android' +application-icon-120:'res/mipmap-anydpi-v26/ic_launcher.xml' +application-icon-160:'res/mipmap-anydpi-v26/ic_launcher.xml' +application-icon-240:'res/mipmap-anydpi-v26/ic_launcher.xml' +application-icon-320:'res/mipmap-anydpi-v26/ic_launcher.xml' +application-icon-480:'res/mipmap-anydpi-v26/ic_launcher.xml' +application-icon-640:'res/mipmap-anydpi-v26/ic_launcher.xml' +application-icon-65534:'res/mipmap-anydpi-v26/ic_launcher.xml' +application: label='Now in Android' icon='res/mipmap-anydpi-v26/ic_launcher.xml' +launchable-activity: name='com.google.samples.apps.nowinandroid.MainActivity' label='' icon='' +uses-library-not-required:'androidx.window.extensions' +uses-library-not-required:'androidx.window.sidecar' +uses-library-not-required:'android.ext.adservices' +feature-group: label='' + uses-feature: name='android.hardware.faketouch' + uses-implied-feature: name='android.hardware.faketouch' reason='default feature for all apps' +main +other-activities +other-receivers +other-services +supports-screens: 'small' 'normal' 'large' 'xlarge' +supports-any-density: 'true' +locales: '--_--' 'af' 'am' 'ar' 'as' 'az' 'be' 'bg' 'bn' 'bs' 'ca' 'cs' 'da' 'de' 'el' 'en-AU' 'en-CA' 'en-GB' 'en-IN' 'en-XC' 'es' 'es-US' 'et' 'eu' 'fa' 'fi' 'fr' 'fr-CA' 'gl' 'gu' 'hi' 'hr' 'hu' 'hy' 'in' 'is' 'it' 'iw' 'ja' 'ka' 'kk' 'km' 'kn' 'ko' 'ky' 'lo' 'lt' 'lv' 'mk' 'ml' 'mn' 'mr' 'ms' 'my' 'nb' 'ne' 'nl' 'or' 'pa' 'pl' 'pt' 'pt-BR' 'pt-PT' 'ro' 'ru' 'si' 'sk' 'sl' 'sq' 'sr' 'sr-Latn' 'sv' 'sw' 'ta' 'te' 'th' 'tl' 'tr' 'uk' 'ur' 'uz' 'vi' 'zh-CN' 'zh-HK' 'zh-TW' 'zu' +densities: '120' '160' '240' '320' '480' '640' '65534' diff --git a/app/src/androidTest/java/com/google/samples/apps/nowinandroid/ui/NavigationTest.kt b/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NavigationTest.kt similarity index 100% rename from app/src/androidTest/java/com/google/samples/apps/nowinandroid/ui/NavigationTest.kt rename to app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NavigationTest.kt diff --git a/app/src/androidTest/java/com/google/samples/apps/nowinandroid/ui/NavigationUiTest.kt b/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NavigationUiTest.kt similarity index 100% rename from app/src/androidTest/java/com/google/samples/apps/nowinandroid/ui/NavigationUiTest.kt rename to app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NavigationUiTest.kt diff --git a/app/src/androidTest/java/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt b/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt similarity index 100% rename from app/src/androidTest/java/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt rename to app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt diff --git a/sync/work/src/demo/AndroidManifest.xml b/app/src/benchmark/res/values-night/colors.xml similarity index 62% rename from sync/work/src/demo/AndroidManifest.xml rename to app/src/benchmark/res/values-night/colors.xml index 8dc32c86f2..677eb4e03e 100644 --- a/sync/work/src/demo/AndroidManifest.xml +++ b/app/src/benchmark/res/values-night/colors.xml @@ -1,6 +1,6 @@ - - - - - - - + + #FFFFFF + #FF006780 + diff --git a/app/src/benchmark/res/values/colors.xml b/app/src/benchmark/res/values/colors.xml new file mode 100644 index 0000000000..d33b7ba72f --- /dev/null +++ b/app/src/benchmark/res/values/colors.xml @@ -0,0 +1,20 @@ + + + + #000000 + #FF006780 + diff --git a/app/src/debug/res/values-night/colors.xml b/app/src/debug/res/values-night/colors.xml new file mode 100644 index 0000000000..d6a4c98e03 --- /dev/null +++ b/app/src/debug/res/values-night/colors.xml @@ -0,0 +1,20 @@ + + + + #FFFFFF + #FFA23F16 + diff --git a/app/src/debug/res/values/colors.xml b/app/src/debug/res/values/colors.xml new file mode 100644 index 0000000000..6365ddb3f7 --- /dev/null +++ b/app/src/debug/res/values/colors.xml @@ -0,0 +1,20 @@ + + + + #000000 + #FFA23F16 + diff --git a/app/src/main/java/com/google/samples/apps/nowinandroid/MainActivity.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt similarity index 100% rename from app/src/main/java/com/google/samples/apps/nowinandroid/MainActivity.kt rename to app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt diff --git a/app/src/main/java/com/google/samples/apps/nowinandroid/MainActivityViewModel.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivityViewModel.kt similarity index 100% rename from app/src/main/java/com/google/samples/apps/nowinandroid/MainActivityViewModel.kt rename to app/src/main/kotlin/com/google/samples/apps/nowinandroid/MainActivityViewModel.kt diff --git a/app/src/main/java/com/google/samples/apps/nowinandroid/NiaApplication.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/NiaApplication.kt similarity index 100% rename from app/src/main/java/com/google/samples/apps/nowinandroid/NiaApplication.kt rename to app/src/main/kotlin/com/google/samples/apps/nowinandroid/NiaApplication.kt diff --git a/app/src/main/java/com/google/samples/apps/nowinandroid/di/JankStatsModule.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/di/JankStatsModule.kt similarity index 100% rename from app/src/main/java/com/google/samples/apps/nowinandroid/di/JankStatsModule.kt rename to app/src/main/kotlin/com/google/samples/apps/nowinandroid/di/JankStatsModule.kt diff --git a/app/src/main/java/com/google/samples/apps/nowinandroid/navigation/NiaNavHost.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/navigation/NiaNavHost.kt similarity index 100% rename from app/src/main/java/com/google/samples/apps/nowinandroid/navigation/NiaNavHost.kt rename to app/src/main/kotlin/com/google/samples/apps/nowinandroid/navigation/NiaNavHost.kt diff --git a/app/src/main/java/com/google/samples/apps/nowinandroid/navigation/TopLevelDestination.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/navigation/TopLevelDestination.kt similarity index 100% rename from app/src/main/java/com/google/samples/apps/nowinandroid/navigation/TopLevelDestination.kt rename to app/src/main/kotlin/com/google/samples/apps/nowinandroid/navigation/TopLevelDestination.kt diff --git a/app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaApp.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt similarity index 100% rename from app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaApp.kt rename to app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaApp.kt diff --git a/app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt b/app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt similarity index 100% rename from app/src/main/java/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt rename to app/src/main/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppState.kt diff --git a/app/src/testDemo/java/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt b/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt similarity index 99% rename from app/src/testDemo/java/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt rename to app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt index 94563abe4b..bac0884821 100644 --- a/app/src/testDemo/java/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt +++ b/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppScreenSizesScreenshotTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2022 The Android Open Source Project + * Copyright 2023 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. @@ -162,7 +162,7 @@ class NiaAppScreenSizesScreenshotTests { @Test fun compactWidth_compactHeight_showsNavigationBar() { testNiaAppScreenshotWithSize( - 610.dp, + 400.dp, 400.dp, "compactWidth_compactHeight_showsNavigationBar", ) diff --git a/app/src/testDemo/screenshots/compactWidth_compactHeight_showsNavigationBar.png b/app/src/testDemo/screenshots/compactWidth_compactHeight_showsNavigationBar.png index 56b49457c1..edb9cfa2af 100644 Binary files a/app/src/testDemo/screenshots/compactWidth_compactHeight_showsNavigationBar.png and b/app/src/testDemo/screenshots/compactWidth_compactHeight_showsNavigationBar.png differ diff --git a/app/src/testDemo/screenshots/expandedWidth_expandedHeight_showsNavigationRail.png b/app/src/testDemo/screenshots/expandedWidth_expandedHeight_showsNavigationRail.png index 25283c1115..523b03ec5b 100644 Binary files a/app/src/testDemo/screenshots/expandedWidth_expandedHeight_showsNavigationRail.png and b/app/src/testDemo/screenshots/expandedWidth_expandedHeight_showsNavigationRail.png differ diff --git a/benchmarks/build.gradle.kts b/benchmarks/build.gradle.kts index 48a6687e41..10c0f7acf6 100644 --- a/benchmarks/build.gradle.kts +++ b/benchmarks/build.gradle.kts @@ -17,7 +17,7 @@ import com.google.samples.apps.nowinandroid.NiaBuildType import com.google.samples.apps.nowinandroid.configureFlavors plugins { - id("nowinandroid.android.test") + alias(libs.plugins.nowinandroid.android.test) } android { diff --git a/benchmarks/src/main/java/androidx/test/uiautomator/UiAutomatorHelpers.kt b/benchmarks/src/main/kotlin/androidx/test/uiautomator/UiAutomatorHelpers.kt similarity index 100% rename from benchmarks/src/main/java/androidx/test/uiautomator/UiAutomatorHelpers.kt rename to benchmarks/src/main/kotlin/androidx/test/uiautomator/UiAutomatorHelpers.kt diff --git a/benchmarks/src/main/java/com/google/samples/apps/nowinandroid/GeneralActions.kt b/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/GeneralActions.kt similarity index 100% rename from benchmarks/src/main/java/com/google/samples/apps/nowinandroid/GeneralActions.kt rename to benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/GeneralActions.kt diff --git a/benchmarks/src/main/java/com/google/samples/apps/nowinandroid/Utils.kt b/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/Utils.kt similarity index 100% rename from benchmarks/src/main/java/com/google/samples/apps/nowinandroid/Utils.kt rename to benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/Utils.kt diff --git a/benchmarks/src/main/java/com/google/samples/apps/nowinandroid/baselineprofile/BaselineProfileGenerator.kt b/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/baselineprofile/BaselineProfileGenerator.kt similarity index 100% rename from benchmarks/src/main/java/com/google/samples/apps/nowinandroid/baselineprofile/BaselineProfileGenerator.kt rename to benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/baselineprofile/BaselineProfileGenerator.kt diff --git a/benchmarks/src/main/java/com/google/samples/apps/nowinandroid/bookmarks/BookmarksActions.kt b/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/bookmarks/BookmarksActions.kt similarity index 100% rename from benchmarks/src/main/java/com/google/samples/apps/nowinandroid/bookmarks/BookmarksActions.kt rename to benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/bookmarks/BookmarksActions.kt diff --git a/benchmarks/src/main/java/com/google/samples/apps/nowinandroid/foryou/ForYouActions.kt b/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/foryou/ForYouActions.kt similarity index 100% rename from benchmarks/src/main/java/com/google/samples/apps/nowinandroid/foryou/ForYouActions.kt rename to benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/foryou/ForYouActions.kt diff --git a/benchmarks/src/main/java/com/google/samples/apps/nowinandroid/foryou/ScrollForYouFeedBenchmark.kt b/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/foryou/ScrollForYouFeedBenchmark.kt similarity index 100% rename from benchmarks/src/main/java/com/google/samples/apps/nowinandroid/foryou/ScrollForYouFeedBenchmark.kt rename to benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/foryou/ScrollForYouFeedBenchmark.kt diff --git a/benchmarks/src/main/java/com/google/samples/apps/nowinandroid/interests/InterestsActions.kt b/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/interests/InterestsActions.kt similarity index 92% rename from benchmarks/src/main/java/com/google/samples/apps/nowinandroid/interests/InterestsActions.kt rename to benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/interests/InterestsActions.kt index d9c563ebc3..c359ae87e0 100644 --- a/benchmarks/src/main/java/com/google/samples/apps/nowinandroid/interests/InterestsActions.kt +++ b/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/interests/InterestsActions.kt @@ -20,6 +20,7 @@ import androidx.benchmark.macro.MacrobenchmarkScope import androidx.test.uiautomator.By import androidx.test.uiautomator.Until import com.google.samples.apps.nowinandroid.flingElementDownUp +import com.google.samples.apps.nowinandroid.waitAndFindObject fun MacrobenchmarkScope.goToInterestsScreen() { device.findObject(By.text("Interests")).click() @@ -34,7 +35,7 @@ fun MacrobenchmarkScope.goToInterestsScreen() { } fun MacrobenchmarkScope.interestsScrollTopicsDownUp() { - val topicsList = device.wait(Until.findObject(By.res("interests:topics")), 2_000) + val topicsList = device.waitAndFindObject(By.res("interests:topics"), 2_000) device.flingElementDownUp(topicsList) } diff --git a/benchmarks/src/main/java/com/google/samples/apps/nowinandroid/interests/ScrollTopicListBenchmark.kt b/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/interests/ScrollTopicListBenchmark.kt similarity index 100% rename from benchmarks/src/main/java/com/google/samples/apps/nowinandroid/interests/ScrollTopicListBenchmark.kt rename to benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/interests/ScrollTopicListBenchmark.kt diff --git a/benchmarks/src/main/java/com/google/samples/apps/nowinandroid/interests/ScrollTopicListPowerMetricsBenchmark.kt b/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/interests/ScrollTopicListPowerMetricsBenchmark.kt similarity index 100% rename from benchmarks/src/main/java/com/google/samples/apps/nowinandroid/interests/ScrollTopicListPowerMetricsBenchmark.kt rename to benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/interests/ScrollTopicListPowerMetricsBenchmark.kt diff --git a/benchmarks/src/main/java/com/google/samples/apps/nowinandroid/interests/TopicsScreenRecompositionBenchmark.kt b/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/interests/TopicsScreenRecompositionBenchmark.kt similarity index 100% rename from benchmarks/src/main/java/com/google/samples/apps/nowinandroid/interests/TopicsScreenRecompositionBenchmark.kt rename to benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/interests/TopicsScreenRecompositionBenchmark.kt diff --git a/benchmarks/src/main/java/com/google/samples/apps/nowinandroid/startup/StartupBenchmark.kt b/benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/startup/StartupBenchmark.kt similarity index 100% rename from benchmarks/src/main/java/com/google/samples/apps/nowinandroid/startup/StartupBenchmark.kt rename to benchmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/startup/StartupBenchmark.kt diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts index 9230dd6b72..b6650aa758 100644 --- a/build-logic/convention/build.gradle.kts +++ b/build-logic/convention/build.gradle.kts @@ -36,6 +36,7 @@ tasks.withType().configureEach { dependencies { compileOnly(libs.android.gradlePlugin) + compileOnly(libs.android.tools.common) compileOnly(libs.firebase.crashlytics.gradlePlugin) compileOnly(libs.firebase.performance.gradlePlugin) compileOnly(libs.kotlin.gradlePlugin) diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt index 50baf3dc6d..f73ed14783 100644 --- a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt @@ -17,11 +17,14 @@ import com.android.build.api.dsl.ApplicationExtension import com.google.samples.apps.nowinandroid.configureGradleManagedDevices import com.android.build.api.variant.ApplicationAndroidComponentsExtension +import com.android.build.gradle.BaseExtension +import com.google.samples.apps.nowinandroid.configureBadgingTasks import com.google.samples.apps.nowinandroid.configureKotlinAndroid import com.google.samples.apps.nowinandroid.configurePrintApksTask import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.getByType class AndroidApplicationConventionPlugin : Plugin { override fun apply(target: Project) { @@ -39,6 +42,7 @@ class AndroidApplicationConventionPlugin : Plugin { } extensions.configure { configurePrintApksTask(this) + configureBadgingTasks(extensions.getByType(), this) } } } diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt index 707ca8055e..05f442354f 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt @@ -18,7 +18,9 @@ import com.android.build.gradle.LibraryExtension import com.google.samples.apps.nowinandroid.configureAndroidCompose import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.kotlin.dsl.dependencies import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.kotlin class AndroidLibraryComposeConventionPlugin : Plugin { override fun apply(target: Project) { diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt index a7c2453187..ef84cfbb4b 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt @@ -47,9 +47,11 @@ class AndroidLibraryConventionPlugin : Plugin { disableUnnecessaryAndroidTests(target) } dependencies { - add("androidTestImplementation", kotlin("test")) add("testImplementation", kotlin("test")) + add("testImplementation", project(":core:testing")) + add("androidTestImplementation", kotlin("test")) + add("androidTestImplementation", project(":core:testing")) } } } -} \ No newline at end of file +} 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 186f0b3d36..614d4f2d0b 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,7 +41,7 @@ internal fun Project.configureAndroidCompose( val bom = libs.findLibrary("androidx-compose-bom").get() add("implementation", platform(bom)) add("androidTestImplementation", platform(bom)) - // Add ComponentActivity to debug manfest + // Add ComponentActivity to debug manifest add("debugImplementation", libs.findLibrary("androidx.compose.ui.testManifest").get()) // Screenshot Tests on JVM add("testImplementation", libs.findLibrary("robolectric").get()) @@ -67,10 +67,10 @@ private fun Project.buildComposeMetricsParameters(): List { val metricParameters = mutableListOf() val enableMetricsProvider = project.providers.gradleProperty("enableComposeCompilerMetrics") val relativePath = projectDir.relativeTo(rootDir) - + val buildDir = layout.buildDirectory.get().asFile val enableMetrics = (enableMetricsProvider.orNull == "true") if (enableMetrics) { - val metricsFolder = rootProject.buildDir.resolve("compose-metrics").resolve(relativePath) + val metricsFolder = buildDir.resolve("compose-metrics").resolve(relativePath) metricParameters.add("-P") metricParameters.add( "plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" + metricsFolder.absolutePath @@ -80,7 +80,7 @@ private fun Project.buildComposeMetricsParameters(): List { val enableReportsProvider = project.providers.gradleProperty("enableComposeCompilerReports") val enableReports = (enableReportsProvider.orNull == "true") if (enableReports) { - val reportsFolder = rootProject.buildDir.resolve("compose-reports").resolve(relativePath) + val reportsFolder = buildDir.resolve("compose-reports").resolve(relativePath) metricParameters.add("-P") metricParameters.add( "plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" + reportsFolder.absolutePath diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Badging.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Badging.kt new file mode 100644 index 0000000000..bcaa00f9fc --- /dev/null +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Badging.kt @@ -0,0 +1,157 @@ +/* + * Copyright 2023 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 + +import com.android.build.api.artifact.SingleArtifact +import com.android.build.api.variant.ApplicationAndroidComponentsExtension +import com.android.build.gradle.BaseExtension +import com.android.SdkConstants +import org.gradle.api.DefaultTask +import org.gradle.api.GradleException +import org.gradle.api.Project +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Copy +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction +import org.gradle.configurationcache.extensions.capitalized +import org.gradle.kotlin.dsl.register +import org.gradle.language.base.plugins.LifecycleBasePlugin +import org.gradle.process.ExecOperations +import java.io.File +import java.nio.file.Files +import javax.inject.Inject + +abstract class GenerateBadgingTask : DefaultTask() { + + @get:OutputFile + abstract val badging: RegularFileProperty + + @get:InputFile + abstract val apk: RegularFileProperty + + @get:InputFile + abstract val aapt2Executable: RegularFileProperty + + @get:Inject + abstract val execOperations: ExecOperations + + @TaskAction + fun taskAction() { + execOperations.exec { + commandLine( + aapt2Executable.get().asFile.absolutePath, + "dump", + "badging", + apk.get().asFile.absolutePath, + ) + standardOutput = badging.asFile.get().outputStream() + } + } +} + +abstract class CheckBadgingTask : DefaultTask() { + + // In order for the task to be up-to-date when the inputs have not changed, + // the task must declare an output, even if it's not used. Tasks with no + // output are always run regardless of whether the inputs changed + @get:OutputDirectory + abstract val output: DirectoryProperty + + @get:InputFile + abstract val goldenBadging: RegularFileProperty + + @get:InputFile + abstract val generatedBadging: RegularFileProperty + + @get:Input + abstract val updateBadgingTaskName: Property + + override fun getGroup(): String = LifecycleBasePlugin.VERIFICATION_GROUP + + @TaskAction + fun taskAction() { + if ( + Files.mismatch( + goldenBadging.get().asFile.toPath(), + generatedBadging.get().asFile.toPath(), + ) != -1L + ) { + throw GradleException( + "Generated badging is different from golden badging! " + + "If this change is intended, run ./gradlew ${updateBadgingTaskName.get()}", + ) + } + } +} + +fun Project.configureBadgingTasks( + baseExtension: BaseExtension, + componentsExtension: ApplicationAndroidComponentsExtension, +) { + // Registers a callback to be called, when a new variant is configured + componentsExtension.onVariants { variant -> + // Registers a new task to verify the app bundle. + val capitalizedVariantName = variant.name.capitalized() + val generateBadgingTaskName = "generate${capitalizedVariantName}Badging" + val generateBadging = + tasks.register(generateBadgingTaskName) { + apk.set( + variant.artifacts.get(SingleArtifact.APK_FROM_BUNDLE), + ) + aapt2Executable.set( + File( + baseExtension.sdkDirectory, + "${SdkConstants.FD_BUILD_TOOLS}/" + + "${baseExtension.buildToolsVersion}/" + + SdkConstants.FN_AAPT2, + ), + ) + + badging.set( + project.layout.buildDirectory.file( + "outputs/apk_from_bundle/${variant.name}/${variant.name}-badging.txt", + ), + ) + } + + val updateBadgingTaskName = "update${capitalizedVariantName}Badging" + tasks.register(updateBadgingTaskName) { + from(generateBadging.get().badging) + into(project.layout.projectDirectory) + } + + val checkBadgingTaskName = "check${capitalizedVariantName}Badging" + tasks.register(checkBadgingTaskName) { + goldenBadging.set( + project.layout.projectDirectory.file("${variant.name}-badging.txt"), + ) + generatedBadging.set( + generateBadging.get().badging, + ) + this.updateBadgingTaskName.set(updateBadgingTaskName) + + output.set( + project.layout.buildDirectory.dir("intermediates/$checkBadgingTaskName"), + ) + } + } +} diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Jacoco.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Jacoco.kt index 70eef1a2db..596c4f5793 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Jacoco.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/Jacoco.kt @@ -50,7 +50,7 @@ internal fun Project.configureJacoco( androidComponentsExtension.onVariants { variant -> val testTaskName = "test${variant.name.capitalize()}UnitTest" - + val buildDir = layout.buildDirectory.get().asFile val reportTask = tasks.register("jacoco${testTaskName.capitalize()}Report", JacocoReport::class) { dependsOn(testTaskName) diff --git a/core/analytics/build.gradle.kts b/core/analytics/build.gradle.kts index 8c573b854e..0f712085ca 100644 --- a/core/analytics/build.gradle.kts +++ b/core/analytics/build.gradle.kts @@ -14,9 +14,9 @@ * limitations under the License. */ plugins { - id("nowinandroid.android.library") - id("nowinandroid.android.library.compose") - id("nowinandroid.android.hilt") + alias(libs.plugins.nowinandroid.android.library) + alias(libs.plugins.nowinandroid.android.library.compose) + alias(libs.plugins.nowinandroid.android.hilt) } android { diff --git a/core/analytics/src/demo/java/com/google/samples/apps/nowinandroid/core/analytics/AnalyticsModule.kt b/core/analytics/src/demo/kotlin/com/google/samples/apps/nowinandroid/core/analytics/AnalyticsModule.kt similarity index 100% rename from core/analytics/src/demo/java/com/google/samples/apps/nowinandroid/core/analytics/AnalyticsModule.kt rename to core/analytics/src/demo/kotlin/com/google/samples/apps/nowinandroid/core/analytics/AnalyticsModule.kt diff --git a/core/analytics/src/main/java/com/google/samples/apps/nowinandroid/core/analytics/AnalyticsEvent.kt b/core/analytics/src/main/kotlin/com/google/samples/apps/nowinandroid/core/analytics/AnalyticsEvent.kt similarity index 100% rename from core/analytics/src/main/java/com/google/samples/apps/nowinandroid/core/analytics/AnalyticsEvent.kt rename to core/analytics/src/main/kotlin/com/google/samples/apps/nowinandroid/core/analytics/AnalyticsEvent.kt diff --git a/core/analytics/src/main/java/com/google/samples/apps/nowinandroid/core/analytics/AnalyticsHelper.kt b/core/analytics/src/main/kotlin/com/google/samples/apps/nowinandroid/core/analytics/AnalyticsHelper.kt similarity index 100% rename from core/analytics/src/main/java/com/google/samples/apps/nowinandroid/core/analytics/AnalyticsHelper.kt rename to core/analytics/src/main/kotlin/com/google/samples/apps/nowinandroid/core/analytics/AnalyticsHelper.kt diff --git a/core/analytics/src/main/java/com/google/samples/apps/nowinandroid/core/analytics/NoOpAnalyticsHelper.kt b/core/analytics/src/main/kotlin/com/google/samples/apps/nowinandroid/core/analytics/NoOpAnalyticsHelper.kt similarity index 100% rename from core/analytics/src/main/java/com/google/samples/apps/nowinandroid/core/analytics/NoOpAnalyticsHelper.kt rename to core/analytics/src/main/kotlin/com/google/samples/apps/nowinandroid/core/analytics/NoOpAnalyticsHelper.kt diff --git a/core/analytics/src/main/java/com/google/samples/apps/nowinandroid/core/analytics/StubAnalyticsHelper.kt b/core/analytics/src/main/kotlin/com/google/samples/apps/nowinandroid/core/analytics/StubAnalyticsHelper.kt similarity index 100% rename from core/analytics/src/main/java/com/google/samples/apps/nowinandroid/core/analytics/StubAnalyticsHelper.kt rename to core/analytics/src/main/kotlin/com/google/samples/apps/nowinandroid/core/analytics/StubAnalyticsHelper.kt diff --git a/core/analytics/src/main/java/com/google/samples/apps/nowinandroid/core/analytics/UiHelpers.kt b/core/analytics/src/main/kotlin/com/google/samples/apps/nowinandroid/core/analytics/UiHelpers.kt similarity index 100% rename from core/analytics/src/main/java/com/google/samples/apps/nowinandroid/core/analytics/UiHelpers.kt rename to core/analytics/src/main/kotlin/com/google/samples/apps/nowinandroid/core/analytics/UiHelpers.kt diff --git a/core/analytics/src/prod/java/com/google/samples/apps/nowinandroid/core/analytics/AnalyticsModule.kt b/core/analytics/src/prod/kotlin/com/google/samples/apps/nowinandroid/core/analytics/AnalyticsModule.kt similarity index 100% rename from core/analytics/src/prod/java/com/google/samples/apps/nowinandroid/core/analytics/AnalyticsModule.kt rename to core/analytics/src/prod/kotlin/com/google/samples/apps/nowinandroid/core/analytics/AnalyticsModule.kt diff --git a/core/analytics/src/prod/java/com/google/samples/apps/nowinandroid/core/analytics/FirebaseAnalyticsHelper.kt b/core/analytics/src/prod/kotlin/com/google/samples/apps/nowinandroid/core/analytics/FirebaseAnalyticsHelper.kt similarity index 100% rename from core/analytics/src/prod/java/com/google/samples/apps/nowinandroid/core/analytics/FirebaseAnalyticsHelper.kt rename to core/analytics/src/prod/kotlin/com/google/samples/apps/nowinandroid/core/analytics/FirebaseAnalyticsHelper.kt diff --git a/core/common/build.gradle.kts b/core/common/build.gradle.kts index 491dffd804..d539d18920 100644 --- a/core/common/build.gradle.kts +++ b/core/common/build.gradle.kts @@ -14,9 +14,9 @@ * limitations under the License. */ plugins { - id("nowinandroid.android.library") - id("nowinandroid.android.library.jacoco") - id("nowinandroid.android.hilt") + alias(libs.plugins.nowinandroid.android.library) + alias(libs.plugins.nowinandroid.android.library.jacoco) + alias(libs.plugins.nowinandroid.android.hilt) } android { @@ -25,5 +25,5 @@ android { dependencies { implementation(libs.kotlinx.coroutines.android) - testImplementation(project(":core:testing")) + testImplementation(projects.core.testing) } \ No newline at end of file diff --git a/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/network/NiaDispatchers.kt b/core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/NiaDispatchers.kt similarity index 100% rename from core/common/src/main/java/com/google/samples/apps/nowinandroid/core/network/NiaDispatchers.kt rename to core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/NiaDispatchers.kt diff --git a/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopesModule.kt b/core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopesModule.kt similarity index 100% rename from core/common/src/main/java/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopesModule.kt rename to core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopesModule.kt diff --git a/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/network/di/DispatchersModule.kt b/core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/DispatchersModule.kt similarity index 100% rename from core/common/src/main/java/com/google/samples/apps/nowinandroid/core/network/di/DispatchersModule.kt rename to core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/DispatchersModule.kt diff --git a/core/common/src/main/java/com/google/samples/apps/nowinandroid/core/result/Result.kt b/core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/result/Result.kt similarity index 100% rename from core/common/src/main/java/com/google/samples/apps/nowinandroid/core/result/Result.kt rename to core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/result/Result.kt diff --git a/core/common/src/test/java/com/google/samples/apps/nowinandroid/core/result/ResultKtTest.kt b/core/common/src/test/kotlin/com/google/samples/apps/nowinandroid/core/result/ResultKtTest.kt similarity index 100% rename from core/common/src/test/java/com/google/samples/apps/nowinandroid/core/result/ResultKtTest.kt rename to core/common/src/test/kotlin/com/google/samples/apps/nowinandroid/core/result/ResultKtTest.kt diff --git a/core/data-test/build.gradle.kts b/core/data-test/build.gradle.kts index dfc224e192..7ca3ecd0dc 100644 --- a/core/data-test/build.gradle.kts +++ b/core/data-test/build.gradle.kts @@ -14,8 +14,8 @@ * limitations under the License. */ plugins { - id("nowinandroid.android.library") - id("nowinandroid.android.hilt") + alias(libs.plugins.nowinandroid.android.library) + alias(libs.plugins.nowinandroid.android.hilt) } android { @@ -23,7 +23,7 @@ android { } dependencies { - api(project(":core:data")) - implementation(project(":core:testing")) - implementation(project(":core:common")) + api(projects.core.data) + implementation(projects.core.testing) + implementation(projects.core.common) } diff --git a/core/data-test/src/main/java/com/google/samples/apps/nowinandroid/core/data/test/AlwaysOnlineNetworkMonitor.kt b/core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/AlwaysOnlineNetworkMonitor.kt similarity index 100% rename from core/data-test/src/main/java/com/google/samples/apps/nowinandroid/core/data/test/AlwaysOnlineNetworkMonitor.kt rename to core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/AlwaysOnlineNetworkMonitor.kt diff --git a/core/data-test/src/main/java/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 similarity index 100% rename from core/data-test/src/main/java/com/google/samples/apps/nowinandroid/core/data/test/TestDataModule.kt rename to core/data-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/test/TestDataModule.kt diff --git a/core/data/build.gradle.kts b/core/data/build.gradle.kts index 51dfb53932..e730a9eb35 100644 --- a/core/data/build.gradle.kts +++ b/core/data/build.gradle.kts @@ -14,9 +14,9 @@ * limitations under the License. */ plugins { - id("nowinandroid.android.library") - id("nowinandroid.android.library.jacoco") - id("nowinandroid.android.hilt") + alias(libs.plugins.nowinandroid.android.library) + alias(libs.plugins.nowinandroid.android.library.jacoco) + alias(libs.plugins.nowinandroid.android.hilt) id("kotlinx-serialization") } @@ -31,18 +31,18 @@ android { } dependencies { - implementation(project(":core:analytics")) - implementation(project(":core:common")) - implementation(project(":core:database")) - implementation(project(":core:datastore")) - implementation(project(":core:model")) - implementation(project(":core:network")) - implementation(project(":core:notifications")) + implementation(projects.core.analytics) + implementation(projects.core.common) + implementation(projects.core.database) + implementation(projects.core.datastore) + implementation(projects.core.model) + implementation(projects.core.network) + implementation(projects.core.notifications) implementation(libs.androidx.core.ktx) implementation(libs.kotlinx.coroutines.android) implementation(libs.kotlinx.datetime) implementation(libs.kotlinx.serialization.json) - testImplementation(project(":core:datastore-test")) - testImplementation(project(":core:testing")) + testImplementation(projects.core.datastoreTest) + testImplementation(projects.core.testing) } diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/SyncUtilities.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/SyncUtilities.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/SyncUtilities.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/SyncUtilities.kt diff --git a/core/data/src/main/java/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 similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/di/DataModule.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/di/DataModule.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/di/UserNewsResourceRepositoryModule.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/di/UserNewsResourceRepositoryModule.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/di/UserNewsResourceRepositoryModule.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/di/UserNewsResourceRepositoryModule.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/model/NewsResource.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/model/NewsResource.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/model/NewsResource.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/model/NewsResource.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/model/RecentSearchQuery.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/model/RecentSearchQuery.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/model/RecentSearchQuery.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/model/RecentSearchQuery.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/model/Topic.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/model/Topic.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/model/Topic.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/model/Topic.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/AnalyticsExtensions.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/AnalyticsExtensions.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/AnalyticsExtensions.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/AnalyticsExtensions.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/CompositeUserNewsResourceRepository.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/CompositeUserNewsResourceRepository.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/CompositeUserNewsResourceRepository.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/CompositeUserNewsResourceRepository.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/DefaultRecentSearchRepository.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/DefaultRecentSearchRepository.kt similarity index 75% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/DefaultRecentSearchRepository.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/DefaultRecentSearchRepository.kt index 983c6af3ef..702c2dcd28 100644 --- a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/DefaultRecentSearchRepository.kt +++ b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/DefaultRecentSearchRepository.kt @@ -20,28 +20,21 @@ import com.google.samples.apps.nowinandroid.core.data.model.RecentSearchQuery import com.google.samples.apps.nowinandroid.core.data.model.asExternalModel import com.google.samples.apps.nowinandroid.core.database.dao.RecentSearchQueryDao import com.google.samples.apps.nowinandroid.core.database.model.RecentSearchQueryEntity -import com.google.samples.apps.nowinandroid.core.network.Dispatcher -import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO -import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map -import kotlinx.coroutines.withContext import kotlinx.datetime.Clock import javax.inject.Inject class DefaultRecentSearchRepository @Inject constructor( private val recentSearchQueryDao: RecentSearchQueryDao, - @Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher, ) : RecentSearchRepository { override suspend fun insertOrReplaceRecentSearch(searchQuery: String) { - withContext(ioDispatcher) { - recentSearchQueryDao.insertOrReplaceRecentSearchQuery( - RecentSearchQueryEntity( - query = searchQuery, - queriedDate = Clock.System.now(), - ), - ) - } + recentSearchQueryDao.insertOrReplaceRecentSearchQuery( + RecentSearchQueryEntity( + query = searchQuery, + queriedDate = Clock.System.now(), + ), + ) } override fun getRecentSearchQueries(limit: Int): Flow> = diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/DefaultSearchContentsRepository.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/DefaultSearchContentsRepository.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/DefaultSearchContentsRepository.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/DefaultSearchContentsRepository.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/NewsRepository.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/NewsRepository.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/NewsRepository.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/NewsRepository.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepository.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepository.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepository.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepository.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepository.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepository.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepository.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepository.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstUserDataRepository.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstUserDataRepository.kt similarity index 92% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstUserDataRepository.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstUserDataRepository.kt index 2559362ba8..a6e41c9da9 100644 --- a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstUserDataRepository.kt +++ b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstUserDataRepository.kt @@ -37,13 +37,13 @@ class OfflineFirstUserDataRepository @Inject constructor( override suspend fun setFollowedTopicIds(followedTopicIds: Set) = niaPreferencesDataSource.setFollowedTopicIds(followedTopicIds) - override suspend fun toggleFollowedTopicId(followedTopicId: String, followed: Boolean) { - niaPreferencesDataSource.toggleFollowedTopicId(followedTopicId, followed) + override suspend fun setTopicIdFollowed(followedTopicId: String, followed: Boolean) { + niaPreferencesDataSource.setTopicIdFollowed(followedTopicId, followed) analyticsHelper.logTopicFollowToggled(followedTopicId, followed) } override suspend fun updateNewsResourceBookmark(newsResourceId: String, bookmarked: Boolean) { - niaPreferencesDataSource.toggleNewsResourceBookmark(newsResourceId, bookmarked) + niaPreferencesDataSource.setNewsResourceBookmarked(newsResourceId, bookmarked) analyticsHelper.logNewsResourceBookmarkToggled( newsResourceId = newsResourceId, isBookmarked = bookmarked, diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/RecentSearchRepository.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/RecentSearchRepository.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/RecentSearchRepository.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/RecentSearchRepository.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/SearchContentsRepository.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/SearchContentsRepository.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/SearchContentsRepository.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/SearchContentsRepository.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/TopicsRepository.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/TopicsRepository.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/TopicsRepository.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/TopicsRepository.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/UserDataRepository.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/UserDataRepository.kt similarity index 93% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/UserDataRepository.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/UserDataRepository.kt index 5e0e7ebfca..ff616c1790 100644 --- a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/UserDataRepository.kt +++ b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/UserDataRepository.kt @@ -34,9 +34,9 @@ interface UserDataRepository { suspend fun setFollowedTopicIds(followedTopicIds: Set) /** - * Toggles the user's newly followed/unfollowed topic + * Sets the user's newly followed/unfollowed topic */ - suspend fun toggleFollowedTopicId(followedTopicId: String, followed: Boolean) + suspend fun setTopicIdFollowed(followedTopicId: String, followed: Boolean) /** * Updates the bookmarked status for a news resource diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/UserNewsResourceRepository.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/UserNewsResourceRepository.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/UserNewsResourceRepository.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/UserNewsResourceRepository.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeNewsRepository.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeNewsRepository.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeNewsRepository.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeNewsRepository.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeRecentSearchRepository.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeRecentSearchRepository.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeRecentSearchRepository.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeRecentSearchRepository.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeSearchContentsRepository.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeSearchContentsRepository.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeSearchContentsRepository.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeSearchContentsRepository.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeTopicsRepository.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeTopicsRepository.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeTopicsRepository.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeTopicsRepository.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeUserDataRepository.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeUserDataRepository.kt similarity index 90% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeUserDataRepository.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeUserDataRepository.kt index 74813389e6..a9da29b56d 100644 --- a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeUserDataRepository.kt +++ b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/fake/FakeUserDataRepository.kt @@ -40,11 +40,11 @@ class FakeUserDataRepository @Inject constructor( override suspend fun setFollowedTopicIds(followedTopicIds: Set) = niaPreferencesDataSource.setFollowedTopicIds(followedTopicIds) - override suspend fun toggleFollowedTopicId(followedTopicId: String, followed: Boolean) = - niaPreferencesDataSource.toggleFollowedTopicId(followedTopicId, followed) + override suspend fun setTopicIdFollowed(followedTopicId: String, followed: Boolean) = + niaPreferencesDataSource.setTopicIdFollowed(followedTopicId, followed) override suspend fun updateNewsResourceBookmark(newsResourceId: String, bookmarked: Boolean) { - niaPreferencesDataSource.toggleNewsResourceBookmark(newsResourceId, bookmarked) + niaPreferencesDataSource.setNewsResourceBookmarked(newsResourceId, bookmarked) } override suspend fun setNewsResourceViewed(newsResourceId: String, viewed: Boolean) = diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/util/ConnectivityManagerNetworkMonitor.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/ConnectivityManagerNetworkMonitor.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/util/ConnectivityManagerNetworkMonitor.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/ConnectivityManagerNetworkMonitor.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/util/NetworkMonitor.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/NetworkMonitor.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/util/NetworkMonitor.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/NetworkMonitor.kt diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/util/SyncManager.kt b/core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/SyncManager.kt similarity index 100% rename from core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/util/SyncManager.kt rename to core/data/src/main/kotlin/com/google/samples/apps/nowinandroid/core/data/util/SyncManager.kt diff --git a/core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/CompositeUserNewsResourceRepositoryTest.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/CompositeUserNewsResourceRepositoryTest.kt similarity index 100% rename from core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/CompositeUserNewsResourceRepositoryTest.kt rename to core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/CompositeUserNewsResourceRepositoryTest.kt diff --git a/core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/UserNewsResourceTest.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/UserNewsResourceTest.kt similarity index 100% rename from core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/UserNewsResourceTest.kt rename to core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/UserNewsResourceTest.kt diff --git a/core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/model/NetworkEntityKtTest.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/model/NetworkEntityKtTest.kt similarity index 100% rename from core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/model/NetworkEntityKtTest.kt rename to core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/model/NetworkEntityKtTest.kt diff --git a/core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt similarity index 100% rename from core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt rename to core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt diff --git a/core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt similarity index 100% rename from core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt rename to core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt diff --git a/core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstUserDataRepositoryTest.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstUserDataRepositoryTest.kt similarity index 98% rename from core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstUserDataRepositoryTest.kt rename to core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstUserDataRepositoryTest.kt index 952f667f79..27e86f2f4c 100644 --- a/core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstUserDataRepositoryTest.kt +++ b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstUserDataRepositoryTest.kt @@ -80,7 +80,7 @@ class OfflineFirstUserDataRepositoryTest { @Test fun offlineFirstUserDataRepository_toggle_followed_topics_logic_delegates_to_nia_preferences() = testScope.runTest { - subject.toggleFollowedTopicId(followedTopicId = "0", followed = true) + subject.setTopicIdFollowed(followedTopicId = "0", followed = true) assertEquals( setOf("0"), @@ -89,7 +89,7 @@ class OfflineFirstUserDataRepositoryTest { .first(), ) - subject.toggleFollowedTopicId(followedTopicId = "1", followed = true) + subject.setTopicIdFollowed(followedTopicId = "1", followed = true) assertEquals( setOf("0", "1"), diff --git a/core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/repository/TestSynchronizer.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/TestSynchronizer.kt similarity index 100% rename from core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/repository/TestSynchronizer.kt rename to core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/TestSynchronizer.kt diff --git a/core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/testdoubles/TestNewsResourceDao.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/testdoubles/TestNewsResourceDao.kt similarity index 100% rename from core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/testdoubles/TestNewsResourceDao.kt rename to core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/testdoubles/TestNewsResourceDao.kt diff --git a/core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/testdoubles/TestNiaNetworkDataSource.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/testdoubles/TestNiaNetworkDataSource.kt similarity index 100% rename from core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/testdoubles/TestNiaNetworkDataSource.kt rename to core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/testdoubles/TestNiaNetworkDataSource.kt diff --git a/core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/testdoubles/TestTopicDao.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/testdoubles/TestTopicDao.kt similarity index 100% rename from core/data/src/test/java/com/google/samples/apps/nowinandroid/core/data/testdoubles/TestTopicDao.kt rename to core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/testdoubles/TestTopicDao.kt diff --git a/core/data/src/test/java/com/google/samples/apps/nowinandroid/core/database/model/PopulatedNewsResourceKtTest.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/database/model/PopulatedNewsResourceKtTest.kt similarity index 100% rename from core/data/src/test/java/com/google/samples/apps/nowinandroid/core/database/model/PopulatedNewsResourceKtTest.kt rename to core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/database/model/PopulatedNewsResourceKtTest.kt diff --git a/core/database/build.gradle.kts b/core/database/build.gradle.kts index a9c711ae33..a1075286da 100644 --- a/core/database/build.gradle.kts +++ b/core/database/build.gradle.kts @@ -15,10 +15,10 @@ */ plugins { - id("nowinandroid.android.library") - id("nowinandroid.android.library.jacoco") - id("nowinandroid.android.hilt") - id("nowinandroid.android.room") + alias(libs.plugins.nowinandroid.android.library) + alias(libs.plugins.nowinandroid.android.library.jacoco) + alias(libs.plugins.nowinandroid.android.hilt) + alias(libs.plugins.nowinandroid.android.room) } android { @@ -30,10 +30,10 @@ android { } dependencies { - implementation(project(":core:model")) + implementation(projects.core.model) implementation(libs.kotlinx.coroutines.android) implementation(libs.kotlinx.datetime) - androidTestImplementation(project(":core:testing")) + androidTestImplementation(projects.core.testing) } diff --git a/core/database/src/androidTest/java/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt similarity index 100% rename from core/database/src/androidTest/java/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt rename to core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt diff --git a/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/DaosModule.kt b/core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/DaosModule.kt similarity index 100% rename from core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/DaosModule.kt rename to core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/DaosModule.kt diff --git a/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/DatabaseMigrations.kt b/core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/DatabaseMigrations.kt similarity index 100% rename from core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/DatabaseMigrations.kt rename to core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/DatabaseMigrations.kt diff --git a/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/DatabaseModule.kt b/core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/DatabaseModule.kt similarity index 100% rename from core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/DatabaseModule.kt rename to core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/DatabaseModule.kt diff --git a/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/NiaDatabase.kt b/core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/NiaDatabase.kt similarity index 100% rename from core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/NiaDatabase.kt rename to core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/NiaDatabase.kt diff --git a/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt b/core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt similarity index 100% rename from core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt rename to core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt diff --git a/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceFtsDao.kt b/core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceFtsDao.kt similarity index 100% rename from core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceFtsDao.kt rename to core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceFtsDao.kt diff --git a/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/RecentSearchQueryDao.kt b/core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/RecentSearchQueryDao.kt similarity index 100% rename from core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/RecentSearchQueryDao.kt rename to core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/RecentSearchQueryDao.kt diff --git a/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/TopicDao.kt b/core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicDao.kt similarity index 100% rename from core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/TopicDao.kt rename to core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicDao.kt diff --git a/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/TopicFtsDao.kt b/core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicFtsDao.kt similarity index 100% rename from core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/dao/TopicFtsDao.kt rename to core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicFtsDao.kt diff --git a/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceEntity.kt b/core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceEntity.kt similarity index 100% rename from core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceEntity.kt rename to core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceEntity.kt diff --git a/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceFtsEntity.kt b/core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceFtsEntity.kt similarity index 100% rename from core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceFtsEntity.kt rename to core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceFtsEntity.kt diff --git a/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceTopicCrossRef.kt b/core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceTopicCrossRef.kt similarity index 100% rename from core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceTopicCrossRef.kt rename to core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceTopicCrossRef.kt diff --git a/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/PopulatedNewsResource.kt b/core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/model/PopulatedNewsResource.kt similarity index 100% rename from core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/PopulatedNewsResource.kt rename to core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/model/PopulatedNewsResource.kt diff --git a/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/RecentSearchQueryEntity.kt b/core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/model/RecentSearchQueryEntity.kt similarity index 100% rename from core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/RecentSearchQueryEntity.kt rename to core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/model/RecentSearchQueryEntity.kt diff --git a/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/TopicEntity.kt b/core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/model/TopicEntity.kt similarity index 100% rename from core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/TopicEntity.kt rename to core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/model/TopicEntity.kt diff --git a/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/TopicFtsEntity.kt b/core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/model/TopicFtsEntity.kt similarity index 100% rename from core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/TopicFtsEntity.kt rename to core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/model/TopicFtsEntity.kt diff --git a/core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/util/InstantConverter.kt b/core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/util/InstantConverter.kt similarity index 100% rename from core/database/src/main/java/com/google/samples/apps/nowinandroid/core/database/util/InstantConverter.kt rename to core/database/src/main/kotlin/com/google/samples/apps/nowinandroid/core/database/util/InstantConverter.kt diff --git a/core/datastore-test/build.gradle.kts b/core/datastore-test/build.gradle.kts index 193c49da74..04b15f0448 100644 --- a/core/datastore-test/build.gradle.kts +++ b/core/datastore-test/build.gradle.kts @@ -14,8 +14,8 @@ * limitations under the License. */ plugins { - id("nowinandroid.android.library") - id("nowinandroid.android.hilt") + alias(libs.plugins.nowinandroid.android.library) + alias(libs.plugins.nowinandroid.android.hilt) } android { @@ -23,10 +23,10 @@ android { } dependencies { - api(project(":core:datastore")) + api(projects.core.datastore) api(libs.androidx.dataStore.core) implementation(libs.protobuf.kotlin.lite) - implementation(project(":core:common")) - implementation(project(":core:testing")) + implementation(projects.core.common) + implementation(projects.core.testing) } diff --git a/core/datastore-test/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/test/TestDataStoreModule.kt b/core/datastore-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/test/TestDataStoreModule.kt similarity index 100% rename from core/datastore-test/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/test/TestDataStoreModule.kt rename to core/datastore-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/test/TestDataStoreModule.kt diff --git a/core/datastore/build.gradle.kts b/core/datastore/build.gradle.kts index 3bbfb77204..7265fd1560 100644 --- a/core/datastore/build.gradle.kts +++ b/core/datastore/build.gradle.kts @@ -15,9 +15,9 @@ */ plugins { - id("nowinandroid.android.library") - id("nowinandroid.android.library.jacoco") - id("nowinandroid.android.hilt") + alias(libs.plugins.nowinandroid.android.library) + alias(libs.plugins.nowinandroid.android.library.jacoco) + alias(libs.plugins.nowinandroid.android.hilt) } android { @@ -34,12 +34,12 @@ android { dependencies { api(project(":core:datastore-proto")) - implementation(project(":core:common")) - implementation(project(":core:model")) + implementation(projects.core.common) + implementation(projects.core.model) implementation(libs.androidx.dataStore.core) implementation(libs.kotlinx.coroutines.android) implementation(libs.protobuf.kotlin.lite) - testImplementation(project(":core:datastore-test")) - testImplementation(project(":core:testing")) + testImplementation(projects.core.datastoreTest) + testImplementation(projects.core.testing) } diff --git a/core/datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/ChangeListVersions.kt b/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/ChangeListVersions.kt similarity index 100% rename from core/datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/ChangeListVersions.kt rename to core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/ChangeListVersions.kt diff --git a/core/datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigration.kt b/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigration.kt similarity index 100% rename from core/datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigration.kt rename to core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigration.kt diff --git a/core/datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/ListToMapMigration.kt b/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/ListToMapMigration.kt similarity index 100% rename from core/datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/ListToMapMigration.kt rename to core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/ListToMapMigration.kt diff --git a/core/datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSource.kt b/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSource.kt similarity index 97% rename from core/datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSource.kt rename to core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSource.kt index 6e2be28089..6dc7725c17 100644 --- a/core/datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSource.kt +++ b/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSource.kt @@ -73,7 +73,7 @@ class NiaPreferencesDataSource @Inject constructor( } } - suspend fun toggleFollowedTopicId(topicId: String, followed: Boolean) { + suspend fun setTopicIdFollowed(topicId: String, followed: Boolean) { try { userPreferences.updateData { it.copy { @@ -122,7 +122,7 @@ class NiaPreferencesDataSource @Inject constructor( } } - suspend fun toggleNewsResourceBookmark(newsResourceId: String, bookmarked: Boolean) { + suspend fun setNewsResourceBookmarked(newsResourceId: String, bookmarked: Boolean) { try { userPreferences.updateData { it.copy { diff --git a/core/datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializer.kt b/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializer.kt similarity index 100% rename from core/datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializer.kt rename to core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializer.kt diff --git a/core/datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt b/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt similarity index 100% rename from core/datastore/src/main/java/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt rename to core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt diff --git a/core/datastore/src/test/java/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigrationTest.kt b/core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigrationTest.kt similarity index 100% rename from core/datastore/src/test/java/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigrationTest.kt rename to core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/IntToStringIdsMigrationTest.kt diff --git a/core/datastore/src/test/java/com/google/samples/apps/nowinandroid/core/datastore/ListToMapMigrationTest.kt b/core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/ListToMapMigrationTest.kt similarity index 100% rename from core/datastore/src/test/java/com/google/samples/apps/nowinandroid/core/datastore/ListToMapMigrationTest.kt rename to core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/ListToMapMigrationTest.kt diff --git a/core/datastore/src/test/java/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSourceTest.kt b/core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSourceTest.kt similarity index 96% rename from core/datastore/src/test/java/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSourceTest.kt rename to core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSourceTest.kt index b865aa4311..433812808f 100644 --- a/core/datastore/src/test/java/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSourceTest.kt +++ b/core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSourceTest.kt @@ -59,11 +59,11 @@ class NiaPreferencesDataSourceTest { fun userShouldHideOnboarding_unfollowsLastTopic_shouldHideOnboardingIsFalse() = testScope.runTest { // Given: user completes onboarding by selecting a single topic. - subject.toggleFollowedTopicId("1", true) + subject.setTopicIdFollowed("1", true) subject.setShouldHideOnboarding(true) // When: they unfollow that topic. - subject.toggleFollowedTopicId("1", false) + subject.setTopicIdFollowed("1", false) // Then: onboarding should be shown again assertFalse(subject.userData.first().shouldHideOnboarding) diff --git a/core/datastore/src/test/java/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializerTest.kt b/core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializerTest.kt similarity index 100% rename from core/datastore/src/test/java/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializerTest.kt rename to core/datastore/src/test/kotlin/com/google/samples/apps/nowinandroid/core/datastore/UserPreferencesSerializerTest.kt diff --git a/core/designsystem/build.gradle.kts b/core/designsystem/build.gradle.kts index cf9873e2c7..7bd1d12d85 100644 --- a/core/designsystem/build.gradle.kts +++ b/core/designsystem/build.gradle.kts @@ -14,9 +14,9 @@ * limitations under the License. */ plugins { - id("nowinandroid.android.library") - id("nowinandroid.android.library.compose") - id("nowinandroid.android.library.jacoco") + alias(libs.plugins.nowinandroid.android.library) + alias(libs.plugins.nowinandroid.android.library.compose) + alias(libs.plugins.nowinandroid.android.library.jacoco) } android { @@ -27,7 +27,7 @@ android { } dependencies { - lintPublish(project(":lint")) + lintPublish(projects.lint) api(libs.androidx.compose.foundation) api(libs.androidx.compose.foundation.layout) @@ -42,5 +42,5 @@ dependencies { implementation(libs.androidx.core.ktx) implementation(libs.coil.kt.compose) - androidTestImplementation(project(":core:testing")) + androidTestImplementation(projects.core.testing) } diff --git a/core/designsystem/src/androidTest/java/com/google/samples/apps/nowinandroid/core/designsystem/ThemeTest.kt b/core/designsystem/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/ThemeTest.kt similarity index 100% rename from core/designsystem/src/androidTest/java/com/google/samples/apps/nowinandroid/core/designsystem/ThemeTest.kt rename to core/designsystem/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/ThemeTest.kt diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/ScrollbarExt.kt b/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/ScrollbarExt.kt deleted file mode 100644 index 26f0bb2aec..0000000000 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/ScrollbarExt.kt +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * 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.designsystem.component.scrollbar - -import androidx.compose.foundation.gestures.Orientation -import androidx.compose.foundation.lazy.LazyListItemInfo -import androidx.compose.foundation.lazy.LazyListState -import androidx.compose.foundation.lazy.grid.LazyGridItemInfo -import androidx.compose.foundation.lazy.grid.LazyGridState -import androidx.compose.runtime.Composable - -/** - * Calculates a [ScrollbarState] driven by the changes in a [LazyListState]. - * - * @param itemsAvailable the total amount of items available to scroll in the lazy list. - * @param itemIndex a lookup function for index of an item in the list relative to [itemsAvailable]. - */ -@Composable -fun LazyListState.scrollbarState( - itemsAvailable: Int, - itemIndex: (LazyListItemInfo) -> Int = LazyListItemInfo::index, -): ScrollbarState = - scrollbarState( - itemsAvailable = itemsAvailable, - visibleItems = { layoutInfo.visibleItemsInfo }, - firstVisibleItemIndex = { visibleItems -> - interpolateFirstItemIndex( - visibleItems = visibleItems, - itemSize = { it.size }, - offset = { it.offset }, - nextItemOnMainAxis = { first -> visibleItems.find { it != first } }, - itemIndex = itemIndex, - ) - }, - itemPercentVisible = itemPercentVisible@{ itemInfo -> - itemVisibilityPercentage( - itemSize = itemInfo.size, - itemStartOffset = itemInfo.offset, - viewportStartOffset = layoutInfo.viewportStartOffset, - viewportEndOffset = layoutInfo.viewportEndOffset, - ) - }, - reverseLayout = { layoutInfo.reverseLayout }, - ) - -/** - * Calculates a [ScrollbarState] driven by the changes in a [LazyGridState] - * - * @param itemsAvailable the total amount of items available to scroll in the grid. - * @param itemIndex a lookup function for index of an item in the grid relative to [itemsAvailable]. - */ -@Composable -fun LazyGridState.scrollbarState( - itemsAvailable: Int, - itemIndex: (LazyGridItemInfo) -> Int = LazyGridItemInfo::index, -): ScrollbarState = - scrollbarState( - itemsAvailable = itemsAvailable, - visibleItems = { layoutInfo.visibleItemsInfo }, - firstVisibleItemIndex = { visibleItems -> - interpolateFirstItemIndex( - visibleItems = visibleItems, - itemSize = { - layoutInfo.orientation.valueOf(it.size) - }, - offset = { layoutInfo.orientation.valueOf(it.offset) }, - nextItemOnMainAxis = { first -> - when (layoutInfo.orientation) { - Orientation.Vertical -> visibleItems.find { - it != first && it.row != first.row - } - - Orientation.Horizontal -> visibleItems.find { - it != first && it.column != first.column - } - } - }, - itemIndex = itemIndex, - ) - }, - itemPercentVisible = itemPercentVisible@{ itemInfo -> - itemVisibilityPercentage( - itemSize = layoutInfo.orientation.valueOf(itemInfo.size), - itemStartOffset = layoutInfo.orientation.valueOf(itemInfo.offset), - viewportStartOffset = layoutInfo.viewportStartOffset, - viewportEndOffset = layoutInfo.viewportEndOffset, - ) - }, - reverseLayout = { layoutInfo.reverseLayout }, - ) diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Background.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Background.kt similarity index 100% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Background.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Background.kt diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Button.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Button.kt similarity index 87% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Button.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Button.kt index e4b437dfec..966014fd95 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Button.kt +++ b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Button.kt @@ -21,15 +21,20 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.sizeIn import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme /** * Now in Android filled button with generic content slot. Wraps Material 3 [Button]. @@ -260,6 +265,50 @@ private fun NiaButtonContent( } } +@ThemePreviews +@Composable +fun NiaButtonPreview() { + NiaTheme { + NiaBackground(modifier = Modifier.size(150.dp, 50.dp)) { + NiaButton(onClick = {}, text = { Text("Test button") }) + } + } +} + +@ThemePreviews +@Composable +fun NiaOutlinedButtonPreview() { + NiaTheme() { + NiaBackground(modifier = Modifier.size(150.dp, 50.dp)) { + NiaOutlinedButton(onClick = {}, text = { Text("Test button") }) + } + } +} + +@ThemePreviews +@Composable +fun NiaButtonPreview2() { + NiaTheme { + NiaBackground(modifier = Modifier.size(150.dp, 50.dp)) { + NiaButton(onClick = {}, text = { Text("Test button") }) + } + } +} + +@ThemePreviews +@Composable +fun NiaButtonLeadingIconPreview() { + NiaTheme { + NiaBackground(modifier = Modifier.size(150.dp, 50.dp)) { + NiaButton( + onClick = {}, + text = { Text("Test button") }, + leadingIcon = { Icon(imageVector = NiaIcons.Add, contentDescription = null) }, + ) + } + } +} + /** * Now in Android button default values. */ diff --git a/core/designsystem/src/main/java/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 similarity index 91% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Chip.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Chip.kt index b291b3fa1e..d1b7d124d6 100644 --- a/core/designsystem/src/main/java/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 @@ -16,6 +16,7 @@ package com.google.samples.apps.nowinandroid.core.designsystem.component +import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.FilterChip @@ -23,11 +24,13 @@ import androidx.compose.material3.FilterChipDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ProvideTextStyle +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme /** * Now in Android filter chip with included leading checked icon as well as text content slot. @@ -103,6 +106,18 @@ fun NiaFilterChip( ) } +@ThemePreviews +@Composable +fun ChipPreview() { + NiaTheme { + NiaBackground(modifier = Modifier.size(80.dp, 20.dp)) { + NiaFilterChip(selected = true, onSelectedChange = {}) { + Text("Chip") + } + } + } +} + /** * Now in Android chip default values. */ diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/DynamicAsyncImage.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/DynamicAsyncImage.kt similarity index 100% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/DynamicAsyncImage.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/DynamicAsyncImage.kt diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/IconButton.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/IconButton.kt similarity index 69% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/IconButton.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/IconButton.kt index b0dda0af1a..503342d30f 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/IconButton.kt +++ b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/IconButton.kt @@ -17,12 +17,15 @@ package com.google.samples.apps.nowinandroid.core.designsystem.component import androidx.compose.material3.FilledIconToggleButton +import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme /** * Now in Android toggle button with icon and checked icon content slots. Wraps Material 3 @@ -68,6 +71,52 @@ fun NiaIconToggleButton( } } +@ThemePreviews +@Composable +fun IconButtonPreview() { + NiaTheme { + NiaIconToggleButton( + checked = true, + onCheckedChange = { }, + icon = { + Icon( + imageVector = NiaIcons.BookmarkBorder, + contentDescription = null, + ) + }, + checkedIcon = { + Icon( + imageVector = NiaIcons.Bookmark, + contentDescription = null, + ) + }, + ) + } +} + +@ThemePreviews +@Composable +fun IconButtonPreviewUnchecked() { + NiaTheme { + NiaIconToggleButton( + checked = false, + onCheckedChange = { }, + icon = { + Icon( + imageVector = NiaIcons.BookmarkBorder, + contentDescription = null, + ) + }, + checkedIcon = { + Icon( + imageVector = NiaIcons.Bookmark, + contentDescription = null, + ) + }, + ) + } +} + /** * Now in Android icon button default values. */ diff --git a/core/designsystem/src/main/java/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 similarity index 99% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/LoadingWheel.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/LoadingWheel.kt index 10ef1bfcee..21dfbc8c37 100644 --- a/core/designsystem/src/main/java/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 @@ -88,6 +88,7 @@ fun NiaLoadingWheel( // Specifies the color animation for the base-to-progress line color change val baseLineColor = MaterialTheme.colorScheme.onBackground val progressLineColor = MaterialTheme.colorScheme.inversePrimary + val colorAnimValues = (0 until NUM_OF_LINES).map { index -> infiniteTransition.animateColor( initialValue = baseLineColor, diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Navigation.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Navigation.kt similarity index 83% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Navigation.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Navigation.kt index 624cf25ac3..f1db03f66a 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Navigation.kt +++ b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Navigation.kt @@ -18,6 +18,7 @@ package com.google.samples.apps.nowinandroid.core.designsystem.component import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.RowScope +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.NavigationBar import androidx.compose.material3.NavigationBarItem @@ -25,10 +26,13 @@ import androidx.compose.material3.NavigationBarItemDefaults import androidx.compose.material3.NavigationRail import androidx.compose.material3.NavigationRailItem import androidx.compose.material3.NavigationRailItemDefaults +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp +import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme /** * Now in Android navigation bar item with icon and label content slots. Wraps Material 3 @@ -161,6 +165,46 @@ fun NiaNavigationRail( ) } +@ThemePreviews +@Composable +fun NiaNavigationPreview() { + val items = listOf("For you", "Saved", "Interests") + val icons = listOf( + NiaIcons.UpcomingBorder, + NiaIcons.BookmarksBorder, + NiaIcons.Grid3x3, + ) + val selectedIcons = listOf( + NiaIcons.Upcoming, + NiaIcons.Bookmarks, + NiaIcons.Grid3x3, + ) + + NiaTheme { + NiaNavigationBar { + items.forEachIndexed { index, item -> + NiaNavigationBarItem( + icon = { + Icon( + imageVector = icons[index], + contentDescription = item, + ) + }, + selectedIcon = { + Icon( + imageVector = selectedIcons[index], + contentDescription = item, + ) + }, + label = { Text(item) }, + selected = index == 0, + onClick = { }, + ) + } + } + } +} + /** * Now in Android navigation default values. */ diff --git a/core/designsystem/src/main/java/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 similarity index 85% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tabs.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Tabs.kt index ad2f3799c1..92cd9aa8f4 100644 --- a/core/designsystem/src/main/java/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 @@ -24,11 +24,15 @@ import androidx.compose.material3.Tab import androidx.compose.material3.TabRow import androidx.compose.material3.TabRowDefaults import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset +import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme /** * Now in Android tab. Wraps Material 3 [Tab] and shifts text label down. @@ -97,6 +101,23 @@ fun NiaTabRow( ) } +@ThemePreviews +@Composable +fun TabsPreview() { + NiaTheme { + val titles = listOf("Topics", "People") + NiaTabRow(selectedTabIndex = 0) { + titles.forEachIndexed { index, title -> + NiaTab( + selected = index == 0, + onClick = { }, + text = { Text(text = title) }, + ) + } + } + } +} + object NiaTabDefaults { val TabTopPadding = 7.dp } diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tag.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Tag.kt similarity index 89% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tag.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Tag.kt index ba8fde1c95..8ca1588a8d 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tag.kt +++ b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Tag.kt @@ -20,10 +20,12 @@ import androidx.compose.foundation.layout.Box import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ProvideTextStyle +import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.contentColorFor import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme @Composable fun NiaTopicTag( @@ -59,6 +61,16 @@ fun NiaTopicTag( } } +@ThemePreviews +@Composable +fun TagPreview() { + NiaTheme { + NiaTopicTag(followed = true, onClick = {}) { + Text("Topic".uppercase()) + } + } +} + /** * Now in Android tag default values. */ diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/TopAppBar.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/TopAppBar.kt similarity index 78% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/TopAppBar.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/TopAppBar.kt index 28007a3b13..99f935d2a8 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/TopAppBar.kt +++ b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/TopAppBar.kt @@ -73,35 +73,6 @@ fun NiaTopAppBar( ) } -/** - * Top app bar with action, displayed on the right - */ -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun NiaTopAppBar( - @StringRes titleRes: Int, - actionIcon: ImageVector, - actionIconContentDescription: String?, - modifier: Modifier = Modifier, - colors: TopAppBarColors = TopAppBarDefaults.centerAlignedTopAppBarColors(), - onActionClick: () -> Unit = {}, -) { - CenterAlignedTopAppBar( - title = { Text(text = stringResource(id = titleRes)) }, - actions = { - IconButton(onClick = onActionClick) { - Icon( - imageVector = actionIcon, - contentDescription = actionIconContentDescription, - tint = MaterialTheme.colorScheme.onSurface, - ) - } - }, - colors = colors, - modifier = modifier.testTag("niaTopAppBar"), - ) -} - @OptIn(ExperimentalMaterial3Api::class) @Preview("Top App Bar") @Composable diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/ViewToggle.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/ViewToggle.kt similarity index 81% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/ViewToggle.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/ViewToggle.kt index c6ec77a922..d368c46d72 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/ViewToggle.kt +++ b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/ViewToggle.kt @@ -24,11 +24,15 @@ import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ProvideTextStyle +import androidx.compose.material3.Surface +import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme /** * Now in Android view toggle button with included trailing icon as well as compact and expanded @@ -105,6 +109,36 @@ private fun NiaViewToggleButtonContent( } } +@ThemePreviews +@Composable +fun ViewTogglePreviewExpanded() { + NiaTheme { + Surface { + NiaViewToggleButton( + expanded = true, + onExpandedChange = { }, + compactText = { Text(text = "Compact view") }, + expandedText = { Text(text = "Expanded view") }, + ) + } + } +} + +@Preview +@Composable +fun ViewTogglePreviewCompact() { + NiaTheme { + Surface { + NiaViewToggleButton( + expanded = false, + onExpandedChange = { }, + compactText = { Text(text = "Compact view") }, + expandedText = { Text(text = "Expanded view") }, + ) + } + } +} + /** * Now in Android view toggle default values. */ diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/AppScrollbars.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/AppScrollbars.kt similarity index 100% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/AppScrollbars.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/AppScrollbars.kt diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/LazyScrollbarUtilities.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/LazyScrollbarUtilities.kt similarity index 56% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/LazyScrollbarUtilities.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/LazyScrollbarUtilities.kt index 8c4063b158..57e567b5d0 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/LazyScrollbarUtilities.kt +++ b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/LazyScrollbarUtilities.kt @@ -17,79 +17,7 @@ package com.google.samples.apps.nowinandroid.core.designsystem.component.scrollbar import androidx.compose.foundation.gestures.ScrollableState -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.runtime.snapshotFlow -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.filterNotNull import kotlin.math.abs -import kotlin.math.min - -/** - * Calculates the [ScrollbarState] for lazy layouts. - * @param itemsAvailable the total amount of items available to scroll in the layout. - * @param visibleItems a list of items currently visible in the layout. - * @param firstVisibleItemIndex a function for interpolating the first visible index in the lazy layout - * as scrolling progresses for smooth and linear scrollbar thumb progression. - * [itemsAvailable]. - * @param reverseLayout if the items in the backing lazy layout are laid out in reverse order. - * */ -@Composable -internal inline fun LazyState.scrollbarState( - itemsAvailable: Int, - crossinline visibleItems: LazyState.() -> List, - crossinline firstVisibleItemIndex: LazyState.(List) -> Float, - crossinline itemPercentVisible: LazyState.(LazyStateItem) -> Float, - crossinline reverseLayout: LazyState.() -> Boolean, -): ScrollbarState { - var state by remember { mutableStateOf(ScrollbarState.FULL) } - - LaunchedEffect( - key1 = this, - key2 = itemsAvailable, - ) { - snapshotFlow { - if (itemsAvailable == 0) return@snapshotFlow null - - val visibleItemsInfo = visibleItems(this@scrollbarState) - if (visibleItemsInfo.isEmpty()) return@snapshotFlow null - - val firstIndex = min( - a = firstVisibleItemIndex(visibleItemsInfo), - b = itemsAvailable.toFloat(), - ) - if (firstIndex.isNaN()) return@snapshotFlow null - - val itemsVisible = visibleItemsInfo.sumOf { - itemPercentVisible(it).toDouble() - }.toFloat() - - val thumbTravelPercent = min( - a = firstIndex / itemsAvailable, - b = 1f, - ) - val thumbSizePercent = min( - a = itemsVisible / itemsAvailable, - b = 1f, - ) - ScrollbarState( - thumbSizePercent = thumbSizePercent, - thumbMovedPercent = when { - reverseLayout() -> 1f - thumbTravelPercent - else -> thumbTravelPercent - }, - ) - } - .filterNotNull() - .distinctUntilChanged() - .collect { state = it } - } - return state -} /** * Linearly interpolates the index for the first item in [visibleItems] for smooth scrollbar diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/Scrollbar.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/Scrollbar.kt similarity index 99% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/Scrollbar.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/Scrollbar.kt index 74d9e04671..c1281a4c03 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/Scrollbar.kt +++ b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/Scrollbar.kt @@ -35,6 +35,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState @@ -205,7 +206,7 @@ fun Scrollbar( // Used to immediately show drag feedback in the UI while the scrolling implementation // catches up - var interactionThumbTravelPercent by remember { mutableStateOf(Float.NaN) } + var interactionThumbTravelPercent by remember { mutableFloatStateOf(Float.NaN) } var track by remember { mutableStateOf(ScrollbarTrack(packedValue = 0)) } diff --git a/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/ScrollbarExt.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/ScrollbarExt.kt new file mode 100644 index 0000000000..7a0282bf7b --- /dev/null +++ b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/ScrollbarExt.kt @@ -0,0 +1,238 @@ +/* + * Copyright 2023 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.designsystem.component.scrollbar + +import androidx.compose.foundation.gestures.Orientation +import androidx.compose.foundation.lazy.LazyListItemInfo +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.grid.LazyGridItemInfo +import androidx.compose.foundation.lazy.grid.LazyGridState +import androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridItemInfo +import androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.produceState +import androidx.compose.runtime.snapshotFlow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.filterNotNull +import kotlin.math.min + +/** + * Calculates a [ScrollbarState] driven by the changes in a [LazyListState]. + * + * @param itemsAvailable the total amount of items available to scroll in the lazy list. + * @param itemIndex a lookup function for index of an item in the list relative to [itemsAvailable]. + */ +@Composable +fun LazyListState.scrollbarState( + itemsAvailable: Int, + itemIndex: (LazyListItemInfo) -> Int = LazyListItemInfo::index, +): ScrollbarState = produceState( + initialValue = ScrollbarState.FULL, + key1 = this, + key2 = itemsAvailable, +) { + snapshotFlow { + if (itemsAvailable == 0) return@snapshotFlow null + + val visibleItemsInfo = layoutInfo.visibleItemsInfo + if (visibleItemsInfo.isEmpty()) return@snapshotFlow null + + val firstIndex = min( + a = interpolateFirstItemIndex( + visibleItems = visibleItemsInfo, + itemSize = { it.size }, + offset = { it.offset }, + nextItemOnMainAxis = { first -> visibleItemsInfo.find { it != first } }, + itemIndex = itemIndex, + ), + b = itemsAvailable.toFloat(), + ) + if (firstIndex.isNaN()) return@snapshotFlow null + + val itemsVisible = visibleItemsInfo.floatSumOf { itemInfo -> + itemVisibilityPercentage( + itemSize = itemInfo.size, + itemStartOffset = itemInfo.offset, + viewportStartOffset = layoutInfo.viewportStartOffset, + viewportEndOffset = layoutInfo.viewportEndOffset, + ) + } + + val thumbTravelPercent = min( + a = firstIndex / itemsAvailable, + b = 1f, + ) + val thumbSizePercent = min( + a = itemsVisible / itemsAvailable, + b = 1f, + ) + ScrollbarState( + thumbSizePercent = thumbSizePercent, + thumbMovedPercent = when { + layoutInfo.reverseLayout -> 1f - thumbTravelPercent + else -> thumbTravelPercent + }, + ) + } + .filterNotNull() + .distinctUntilChanged() + .collect { value = it } +}.value + +/** + * Calculates a [ScrollbarState] driven by the changes in a [LazyGridState] + * + * @param itemsAvailable the total amount of items available to scroll in the grid. + * @param itemIndex a lookup function for index of an item in the grid relative to [itemsAvailable]. + */ +@Composable +fun LazyGridState.scrollbarState( + itemsAvailable: Int, + itemIndex: (LazyGridItemInfo) -> Int = LazyGridItemInfo::index, +): ScrollbarState = produceState( + initialValue = ScrollbarState.FULL, + key1 = this, + key2 = itemsAvailable, +) { + snapshotFlow { + if (itemsAvailable == 0) return@snapshotFlow null + + val visibleItemsInfo = layoutInfo.visibleItemsInfo + if (visibleItemsInfo.isEmpty()) return@snapshotFlow null + + val firstIndex = min( + a = interpolateFirstItemIndex( + visibleItems = visibleItemsInfo, + itemSize = { layoutInfo.orientation.valueOf(it.size) }, + offset = { layoutInfo.orientation.valueOf(it.offset) }, + nextItemOnMainAxis = { first -> + when (layoutInfo.orientation) { + Orientation.Vertical -> visibleItemsInfo.find { + it != first && it.row != first.row + } + + Orientation.Horizontal -> visibleItemsInfo.find { + it != first && it.column != first.column + } + } + }, + itemIndex = itemIndex, + ), + b = itemsAvailable.toFloat(), + ) + if (firstIndex.isNaN()) return@snapshotFlow null + + val itemsVisible = visibleItemsInfo.floatSumOf { itemInfo -> + itemVisibilityPercentage( + itemSize = layoutInfo.orientation.valueOf(itemInfo.size), + itemStartOffset = layoutInfo.orientation.valueOf(itemInfo.offset), + viewportStartOffset = layoutInfo.viewportStartOffset, + viewportEndOffset = layoutInfo.viewportEndOffset, + ) + } + + val thumbTravelPercent = min( + a = firstIndex / itemsAvailable, + b = 1f, + ) + val thumbSizePercent = min( + a = itemsVisible / itemsAvailable, + b = 1f, + ) + ScrollbarState( + thumbSizePercent = thumbSizePercent, + thumbMovedPercent = when { + layoutInfo.reverseLayout -> 1f - thumbTravelPercent + else -> thumbTravelPercent + }, + ) + } + .filterNotNull() + .distinctUntilChanged() + .collect { value = it } +}.value + +/** + * Remembers a [ScrollbarState] driven by the changes in a [LazyStaggeredGridState] + * + * @param itemsAvailable the total amount of items available to scroll in the staggered grid. + * @param itemIndex a lookup function for index of an item in the staggered grid relative + * to [itemsAvailable]. + */ +@Composable +fun LazyStaggeredGridState.scrollbarState( + itemsAvailable: Int, + itemIndex: (LazyStaggeredGridItemInfo) -> Int = LazyStaggeredGridItemInfo::index, +): ScrollbarState = produceState( + initialValue = ScrollbarState.FULL, + key1 = this, + key2 = itemsAvailable, +) { + snapshotFlow { + if (itemsAvailable == 0) return@snapshotFlow null + + val visibleItemsInfo = layoutInfo.visibleItemsInfo + if (visibleItemsInfo.isEmpty()) return@snapshotFlow null + + val firstIndex = min( + a = interpolateFirstItemIndex( + visibleItems = visibleItemsInfo, + itemSize = { layoutInfo.orientation.valueOf(it.size) }, + offset = { layoutInfo.orientation.valueOf(it.offset) }, + nextItemOnMainAxis = { first -> + visibleItemsInfo.find { it != first && it.lane == first.lane } + }, + itemIndex = itemIndex, + ), + b = itemsAvailable.toFloat(), + ) + if (firstIndex.isNaN()) return@snapshotFlow null + + val itemsVisible = visibleItemsInfo.floatSumOf { itemInfo -> + itemVisibilityPercentage( + itemSize = layoutInfo.orientation.valueOf(itemInfo.size), + itemStartOffset = layoutInfo.orientation.valueOf(itemInfo.offset), + viewportStartOffset = layoutInfo.viewportStartOffset, + viewportEndOffset = layoutInfo.viewportEndOffset, + ) + } + + val thumbTravelPercent = min( + a = firstIndex / itemsAvailable, + b = 1f, + ) + val thumbSizePercent = min( + a = itemsVisible / itemsAvailable, + b = 1f, + ) + ScrollbarState( + thumbSizePercent = thumbSizePercent, + thumbMovedPercent = thumbTravelPercent, + ) + } + .filterNotNull() + .distinctUntilChanged() + .collect { value = it } +}.value + +private inline fun List.floatSumOf(selector: (T) -> Float): Float { + var sum = 0f + for (element in this) { + sum += selector(element) + } + return sum +} diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/ThumbExt.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/ThumbExt.kt similarity index 81% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/ThumbExt.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/ThumbExt.kt index 4d187e2693..8475803613 100644 --- a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/ThumbExt.kt +++ b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/scrollbar/ThumbExt.kt @@ -18,10 +18,11 @@ package com.google.samples.apps.nowinandroid.core.designsystem.component.scrollb import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.grid.LazyGridState +import androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue @@ -50,6 +51,19 @@ fun LazyGridState.rememberDraggableScroller( scroll = ::scrollToItem, ) +/** + * Remembers a function to react to [Scrollbar] thumb position displacements for a + * [LazyStaggeredGridState] + * @param itemsAvailable the amount of items in the staggered grid. + */ +@Composable +fun LazyStaggeredGridState.rememberDraggableScroller( + itemsAvailable: Int, +): (Float) -> Unit = rememberDraggableScroller( + itemsAvailable = itemsAvailable, + scroll = ::scrollToItem, +) + /** * Generic function to react to [Scrollbar] thumb displacements in a lazy layout. * @param itemsAvailable the total amount of items available to scroll in the layout. @@ -60,7 +74,7 @@ private inline fun rememberDraggableScroller( itemsAvailable: Int, crossinline scroll: suspend (index: Int) -> Unit, ): (Float) -> Unit { - var percentage by remember { mutableStateOf(Float.NaN) } + var percentage by remember { mutableFloatStateOf(Float.NaN) } val itemCount by rememberUpdatedState(itemsAvailable) LaunchedEffect(percentage) { diff --git a/core/designsystem/src/main/java/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 similarity index 100% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/icon/NiaIcons.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/icon/NiaIcons.kt diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/theme/Background.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/theme/Background.kt similarity index 100% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/theme/Background.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/theme/Background.kt diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/theme/Color.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/theme/Color.kt similarity index 100% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/theme/Color.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/theme/Color.kt diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/theme/Gradient.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/theme/Gradient.kt similarity index 100% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/theme/Gradient.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/theme/Gradient.kt diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/theme/Theme.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/theme/Theme.kt similarity index 100% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/theme/Theme.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/theme/Theme.kt diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/theme/Tint.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/theme/Tint.kt similarity index 100% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/theme/Tint.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/theme/Tint.kt diff --git a/core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/theme/Type.kt b/core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/theme/Type.kt similarity index 100% rename from core/designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/theme/Type.kt rename to core/designsystem/src/main/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/theme/Type.kt diff --git a/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/BackgroundScreenshotTests.kt b/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/BackgroundScreenshotTests.kt new file mode 100644 index 0000000000..d3349de801 --- /dev/null +++ b/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/BackgroundScreenshotTests.kt @@ -0,0 +1,63 @@ +/* + * Copyright 2023 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.designsystem + +import androidx.activity.ComponentActivity +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Text +import androidx.compose.ui.Modifier +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.unit.dp +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.testing.util.captureMultiTheme +import dagger.hilt.android.testing.HiltTestApplication +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode +import org.robolectric.annotation.LooperMode + +@RunWith(RobolectricTestRunner::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +@Config(application = HiltTestApplication::class, sdk = [33], qualifiers = "480dpi") +@LooperMode(LooperMode.Mode.PAUSED) +class BackgroundScreenshotTests { + + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @Test + fun niaBackground_multipleThemes() { + composeTestRule.captureMultiTheme("Background") { description -> + NiaBackground(Modifier.size(100.dp)) { + Text("$description background") + } + } + } + + @Test + fun niaGradientBackground_multipleThemes() { + composeTestRule.captureMultiTheme("Background", "GradientBackground") { description -> + NiaGradientBackground(Modifier.size(100.dp)) { + Text("$description background") + } + } + } +} diff --git a/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/ButtonScreenshotTests.kt b/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/ButtonScreenshotTests.kt new file mode 100644 index 0000000000..d3aa4224f1 --- /dev/null +++ b/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/ButtonScreenshotTests.kt @@ -0,0 +1,80 @@ +/* + * Copyright 2023 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.designsystem + +import androidx.activity.ComponentActivity +import androidx.compose.material3.Icon +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaButton +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaOutlinedButton +import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons +import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme +import dagger.hilt.android.testing.HiltTestApplication +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode +import org.robolectric.annotation.LooperMode + +@RunWith(RobolectricTestRunner::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +@Config(application = HiltTestApplication::class, sdk = [33], qualifiers = "480dpi") +@LooperMode(LooperMode.Mode.PAUSED) +class ButtonScreenshotTests { + + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @Test + fun niaButton_multipleThemes() { + composeTestRule.captureMultiTheme("Button") { description -> + Surface { + NiaButton(onClick = {}, text = { Text("$description Button") }) + } + } + } + + @Test + fun niaOutlineButton_multipleThemes() { + composeTestRule.captureMultiTheme("Button", "OutlineButton") { description -> + Surface { + NiaOutlinedButton(onClick = {}, text = { Text("$description OutlineButton") }) + } + } + } + + @Test + fun niaButton_leadingIcon_multipleThemes() { + composeTestRule.captureMultiTheme( + name = "Button", + overrideFileName = "ButtonLeadingIcon", + shouldCompareAndroidTheme = false, + ) { description -> + Surface { + NiaButton( + onClick = {}, + text = { Text("$description Icon Button") }, + leadingIcon = { Icon(imageVector = NiaIcons.Add, contentDescription = null) }, + ) + } + } + } +} diff --git a/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/FilterChipScreenshotTests.kt b/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/FilterChipScreenshotTests.kt new file mode 100644 index 0000000000..510a0dcfce --- /dev/null +++ b/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/FilterChipScreenshotTests.kt @@ -0,0 +1,98 @@ +/* + * Copyright 2023 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.designsystem + +import androidx.activity.ComponentActivity +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.platform.LocalInspectionMode +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onRoot +import androidx.compose.ui.unit.DpSize +import androidx.compose.ui.unit.dp +import com.github.takahirom.roborazzi.captureRoboImage +import com.google.accompanist.testharness.TestHarness +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaBackground +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaFilterChip +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme +import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions +import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme +import dagger.hilt.android.testing.HiltTestApplication +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode +import org.robolectric.annotation.LooperMode + +@RunWith(RobolectricTestRunner::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +@Config(application = HiltTestApplication::class, sdk = [33], qualifiers = "480dpi") +@LooperMode(LooperMode.Mode.PAUSED) +class FilterChipScreenshotTests() { + + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @Test + fun filterChip_multipleThemes() { + composeTestRule.captureMultiTheme("FilterChip") { + Surface { + NiaFilterChip(selected = false, onSelectedChange = {}) { + Text("Unselected chip") + } + } + } + } + + @Test + fun filterChip_multipleThemes_selected() { + composeTestRule.captureMultiTheme("FilterChip", "FilterChipSelected") { + Surface { + NiaFilterChip(selected = true, onSelectedChange = {}) { + Text("Selected Chip") + } + } + } + } + + @Test + fun filterChip_hugeFont() { + composeTestRule.setContent { + CompositionLocalProvider( + LocalInspectionMode provides true, + ) { + TestHarness(fontScale = 2f, size = DpSize(80.dp, 40.dp)) { + NiaTheme { + NiaBackground { + NiaFilterChip(selected = true, onSelectedChange = {}) { + Text("Chip") + } + } + } + } + } + } + composeTestRule.onRoot() + .captureRoboImage( + "src/test/screenshots/FilterChip/FilterChip_fontScale2.png", + roborazziOptions = DefaultRoborazziOptions, + ) + } +} diff --git a/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/IconButtonScreenshotTests.kt b/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/IconButtonScreenshotTests.kt new file mode 100644 index 0000000000..f6d71fe77f --- /dev/null +++ b/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/IconButtonScreenshotTests.kt @@ -0,0 +1,80 @@ +/* + * Copyright 2023 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.designsystem + +import androidx.activity.ComponentActivity +import androidx.compose.material3.Icon +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaIconToggleButton +import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons +import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme +import dagger.hilt.android.testing.HiltTestApplication +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode +import org.robolectric.annotation.LooperMode + +@RunWith(RobolectricTestRunner::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +@Config(application = HiltTestApplication::class, sdk = [33], qualifiers = "480dpi") +@LooperMode(LooperMode.Mode.PAUSED) +class IconButtonScreenshotTests { + + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @Test + fun iconButton_multipleThemes() { + composeTestRule.captureMultiTheme("IconButton") { + NiaIconToggleExample(false) + } + } + + @Test + fun iconButton_unchecked_multipleThemes() { + composeTestRule.captureMultiTheme("IconButton", "IconButtonUnchecked") { + Surface { + NiaIconToggleExample(true) + } + } + } + + @Composable + private fun NiaIconToggleExample(checked: Boolean) { + NiaIconToggleButton( + checked = checked, + onCheckedChange = { }, + icon = { + Icon( + imageVector = NiaIcons.BookmarkBorder, + contentDescription = null, + ) + }, + checkedIcon = { + Icon( + imageVector = NiaIcons.Bookmark, + contentDescription = null, + ) + }, + ) + } +} diff --git a/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/LoadingWheelScreenshotTests.kt b/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/LoadingWheelScreenshotTests.kt new file mode 100644 index 0000000000..412f42370b --- /dev/null +++ b/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/LoadingWheelScreenshotTests.kt @@ -0,0 +1,83 @@ +/* + * Copyright 2023 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.designsystem + +import androidx.activity.ComponentActivity +import androidx.compose.material3.Surface +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onRoot +import com.github.takahirom.roborazzi.captureRoboImage +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadingWheel +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaOverlayLoadingWheel +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme +import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions +import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme +import dagger.hilt.android.testing.HiltTestApplication +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode +import org.robolectric.annotation.LooperMode + +@RunWith(RobolectricTestRunner::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +@Config(application = HiltTestApplication::class, sdk = [33], qualifiers = "480dpi") +@LooperMode(LooperMode.Mode.PAUSED) +class LoadingWheelScreenshotTests() { + + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @Test + fun loadingWheel_multipleThemes() { + composeTestRule.captureMultiTheme("LoadingWheel") { + Surface { + NiaLoadingWheel(contentDesc = "test") + } + } + } + + @Test + fun overlayLoadingWheel_multipleThemes() { + composeTestRule.captureMultiTheme("LoadingWheel", "OverlayLoadingWheel") { + Surface { + NiaOverlayLoadingWheel(contentDesc = "test") + } + } + } + + @Test + fun loadingWheelAnimation() { + composeTestRule.mainClock.autoAdvance = false + composeTestRule.setContent { + NiaTheme() { + NiaLoadingWheel(contentDesc = "") + } + } + // Try multiple frames of the animation; some arbitrary, some synchronized with duration. + listOf(20L, 115L, 724L, 1000L).forEach { deltaTime -> + composeTestRule.mainClock.advanceTimeBy(deltaTime) + composeTestRule.onRoot() + .captureRoboImage( + "src/test/screenshots/LoadingWheel/LoadingWheel_animation_$deltaTime.png", + roborazziOptions = DefaultRoborazziOptions, + ) + } + } +} diff --git a/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/NavigationScreenshotTests.kt b/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/NavigationScreenshotTests.kt new file mode 100644 index 0000000000..05976ba470 --- /dev/null +++ b/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/NavigationScreenshotTests.kt @@ -0,0 +1,108 @@ +/* + * Copyright 2023 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.designsystem + +import androidx.activity.ComponentActivity +import androidx.compose.material3.Icon +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.platform.LocalInspectionMode +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onRoot +import com.github.takahirom.roborazzi.captureRoboImage +import com.google.accompanist.testharness.TestHarness +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavigationBar +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaNavigationBarItem +import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme +import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions +import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme +import dagger.hilt.android.testing.HiltTestApplication +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode +import org.robolectric.annotation.LooperMode + +@RunWith(RobolectricTestRunner::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +@Config(application = HiltTestApplication::class, sdk = [33], qualifiers = "480dpi") +@LooperMode(LooperMode.Mode.PAUSED) +class NavigationScreenshotTests() { + + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @Test + fun navigation_multipleThemes() { + composeTestRule.captureMultiTheme("Navigation") { + Surface { + NiaNavigationBarExample() + } + } + } + + @Test + fun navigation_hugeFont() { + composeTestRule.setContent { + CompositionLocalProvider( + LocalInspectionMode provides true, + ) { + TestHarness(fontScale = 2f) { + NiaTheme { + NiaNavigationBarExample("Looong item") + } + } + } + } + composeTestRule.onRoot() + .captureRoboImage( + "src/test/screenshots/Navigation" + + "/Navigation_fontScale2.png", + roborazziOptions = DefaultRoborazziOptions, + ) + } + + @Composable + private fun NiaNavigationBarExample(label: String = "Item") { + NiaNavigationBar { + (0..2).forEach { index -> + NiaNavigationBarItem( + icon = { + Icon( + imageVector = NiaIcons.UpcomingBorder, + contentDescription = "", + ) + }, + selectedIcon = { + Icon( + imageVector = NiaIcons.Upcoming, + contentDescription = "", + ) + }, + label = { Text(label) }, + selected = index == 0, + onClick = { }, + ) + } + } + } +} diff --git a/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TabsScreenshotTests.kt b/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TabsScreenshotTests.kt new file mode 100644 index 0000000000..76117db2e6 --- /dev/null +++ b/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TabsScreenshotTests.kt @@ -0,0 +1,94 @@ +/* + * Copyright 2023 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.designsystem + +import androidx.activity.ComponentActivity +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.platform.LocalInspectionMode +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onRoot +import com.github.takahirom.roborazzi.captureRoboImage +import com.google.accompanist.testharness.TestHarness +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTab +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTabRow +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme +import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions +import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme +import dagger.hilt.android.testing.HiltTestApplication +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode +import org.robolectric.annotation.LooperMode + +@RunWith(RobolectricTestRunner::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +@Config(application = HiltTestApplication::class, sdk = [33], qualifiers = "480dpi") +@LooperMode(LooperMode.Mode.PAUSED) +class TabsScreenshotTests() { + + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @Test + fun tabs_multipleThemes() { + composeTestRule.captureMultiTheme("Tabs") { + NiaTabsExample() + } + } + + @Test + fun tabs_hugeFont() { + composeTestRule.setContent { + CompositionLocalProvider( + LocalInspectionMode provides true, + ) { + TestHarness(fontScale = 2f) { + NiaTheme { + NiaTabsExample("Looooong item") + } + } + } + } + composeTestRule.onRoot() + .captureRoboImage( + "src/test/screenshots/Tabs/Tabs_fontScale2.png", + roborazziOptions = DefaultRoborazziOptions, + ) + } + + @Composable + private fun NiaTabsExample(label: String = "Topics") { + Surface { + val titles = listOf(label, "People") + NiaTabRow(selectedTabIndex = 0) { + titles.forEachIndexed { index, title -> + NiaTab( + selected = index == 0, + onClick = { }, + text = { Text(text = title) }, + ) + } + } + } + } +} diff --git a/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TagScreenshotTests.kt b/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TagScreenshotTests.kt new file mode 100644 index 0000000000..9db4d02a31 --- /dev/null +++ b/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TagScreenshotTests.kt @@ -0,0 +1,79 @@ +/* + * Copyright 2023 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.designsystem + +import androidx.activity.ComponentActivity +import androidx.compose.material3.Text +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.platform.LocalInspectionMode +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onRoot +import com.github.takahirom.roborazzi.captureRoboImage +import com.google.accompanist.testharness.TestHarness +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopicTag +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme +import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions +import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme +import dagger.hilt.android.testing.HiltTestApplication +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode +import org.robolectric.annotation.LooperMode + +@RunWith(RobolectricTestRunner::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +@Config(application = HiltTestApplication::class, sdk = [33], qualifiers = "480dpi") +@LooperMode(LooperMode.Mode.PAUSED) +class TagScreenshotTests() { + + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @Test + fun Tag_multipleThemes() { + composeTestRule.captureMultiTheme("Tag") { + NiaTopicTag(followed = true, onClick = {}) { + Text("TOPIC") + } + } + } + + @Test + fun tag_hugeFont() { + composeTestRule.setContent { + CompositionLocalProvider( + LocalInspectionMode provides true, + ) { + TestHarness(fontScale = 2f) { + NiaTheme { + NiaTopicTag(followed = true, onClick = {}) { + Text("LOOOOONG TOPIC") + } + } + } + } + } + composeTestRule.onRoot() + .captureRoboImage( + "src/test/screenshots/Tag/Tag_fontScale2.png", + roborazziOptions = DefaultRoborazziOptions, + ) + } +} diff --git a/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TopAppBarScreenshotTests.kt b/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TopAppBarScreenshotTests.kt new file mode 100644 index 0000000000..29404da790 --- /dev/null +++ b/core/designsystem/src/test/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/TopAppBarScreenshotTests.kt @@ -0,0 +1,90 @@ +/* + * Copyright 2023 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.designsystem + +import android.R.string +import androidx.activity.ComponentActivity +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.platform.LocalInspectionMode +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onRoot +import com.github.takahirom.roborazzi.captureRoboImage +import com.google.accompanist.testharness.TestHarness +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaTopAppBar +import com.google.samples.apps.nowinandroid.core.designsystem.icon.NiaIcons +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme +import com.google.samples.apps.nowinandroid.core.testing.util.DefaultRoborazziOptions +import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiTheme +import dagger.hilt.android.testing.HiltTestApplication +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config +import org.robolectric.annotation.GraphicsMode +import org.robolectric.annotation.LooperMode + +@OptIn(ExperimentalMaterial3Api::class) +@RunWith(RobolectricTestRunner::class) +@GraphicsMode(GraphicsMode.Mode.NATIVE) +@Config(application = HiltTestApplication::class, sdk = [33], qualifiers = "480dpi") +@LooperMode(LooperMode.Mode.PAUSED) +class TopAppBarScreenshotTests() { + + @get:Rule + val composeTestRule = createAndroidComposeRule() + + @Test + fun topAppBar_multipleThemes() { + composeTestRule.captureMultiTheme("TopAppBar") { + NiaTopAppBarExample() + } + } + + @Test + fun topAppBar_hugeFont() { + composeTestRule.setContent { + CompositionLocalProvider( + LocalInspectionMode provides true, + ) { + TestHarness(fontScale = 2f) { + NiaTheme { + NiaTopAppBarExample() + } + } + } + } + composeTestRule.onRoot() + .captureRoboImage( + "src/test/screenshots/TopAppBar/TopAppBar_fontScale2.png", + roborazziOptions = DefaultRoborazziOptions, + ) + } + + @Composable + private fun NiaTopAppBarExample() { + NiaTopAppBar( + titleRes = android.R.string.untitled, + navigationIcon = NiaIcons.Search, + navigationIconContentDescription = "Navigation icon", + actionIcon = NiaIcons.MoreVert, + actionIconContentDescription = "Action icon", + ) + } +} diff --git a/core/designsystem/src/test/screenshots/Background/Background_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/Background_dark_androidTheme_notDynamic.png new file mode 100644 index 0000000000..34b6b95898 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/Background_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_dynamic.png new file mode 100644 index 0000000000..c4a4d7440c Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..4eb46a8e68 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/Background_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/Background_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/Background_light_androidTheme_notDynamic.png new file mode 100644 index 0000000000..d2914c4518 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/Background_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_dynamic.png new file mode 100644 index 0000000000..9b4d62d865 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..22eaf5833d Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/Background_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_androidTheme_notDynamic.png new file mode 100644 index 0000000000..34b6b95898 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_dynamic.png new file mode 100644 index 0000000000..35449ae14a Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..ce588b0ee7 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/GradientBackground_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/GradientBackground_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/GradientBackground_light_androidTheme_notDynamic.png new file mode 100644 index 0000000000..d2914c4518 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/GradientBackground_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_dynamic.png new file mode 100644 index 0000000000..84a3dcaa72 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..cc8ccd9973 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Background/GradientBackground_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_dynamic.png new file mode 100644 index 0000000000..9ddd58d4b7 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..9514112f1e Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_dynamic.png new file mode 100644 index 0000000000..c867bf469a Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..8858fb493f Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/ButtonLeadingIcon_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/Button_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/Button_dark_androidTheme_notDynamic.png new file mode 100644 index 0000000000..a5d3d4a3dc Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/Button_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_dynamic.png new file mode 100644 index 0000000000..386760d240 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..cd0c07df1a Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/Button_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/Button_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/Button_light_androidTheme_notDynamic.png new file mode 100644 index 0000000000..ab113beec1 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/Button_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_dynamic.png new file mode 100644 index 0000000000..d817e5c3f8 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..b567adf840 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/Button_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_androidTheme_notDynamic.png new file mode 100644 index 0000000000..a9ba099c05 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_dynamic.png new file mode 100644 index 0000000000..4a8fe7a981 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..ce30b66ba5 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/OutlineButton_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/OutlineButton_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/OutlineButton_light_androidTheme_notDynamic.png new file mode 100644 index 0000000000..bb6aa592f6 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/OutlineButton_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_dynamic.png new file mode 100644 index 0000000000..4dce1bcab8 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..d2059e4d7c Binary files /dev/null and b/core/designsystem/src/test/screenshots/Button/OutlineButton_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_androidTheme_notDynamic.png new file mode 100644 index 0000000000..5881f76b73 Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_dynamic.png new file mode 100644 index 0000000000..d73f023c83 Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..f2e8638650 Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_androidTheme_notDynamic.png new file mode 100644 index 0000000000..1e3b04e507 Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_dynamic.png new file mode 100644 index 0000000000..e363c8dad8 Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..be73f060d3 Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChipSelected_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_androidTheme_notDynamic.png new file mode 100644 index 0000000000..364f59a472 Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_dynamic.png new file mode 100644 index 0000000000..7c0371ddcf Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..5303eb64ea Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_fontScale2.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_fontScale2.png new file mode 100644 index 0000000000..56ddf9792c Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_fontScale2.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_androidTheme_notDynamic.png new file mode 100644 index 0000000000..fadd074d8b Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_dynamic.png new file mode 100644 index 0000000000..c73df7f892 Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..0cfaaefae2 Binary files /dev/null and b/core/designsystem/src/test/screenshots/FilterChip/FilterChip_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_androidTheme_notDynamic.png new file mode 100644 index 0000000000..a1512fa75b Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_dynamic.png new file mode 100644 index 0000000000..5e732c373c Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..f912ce3c1b Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_androidTheme_notDynamic.png new file mode 100644 index 0000000000..3394797790 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_dynamic.png new file mode 100644 index 0000000000..b7eb3db4a0 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..24580adf28 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButtonUnchecked_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_androidTheme_notDynamic.png new file mode 100644 index 0000000000..ce2cdf8045 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_dynamic.png new file mode 100644 index 0000000000..ce2cdf8045 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..ce2cdf8045 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButton_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButton_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButton_light_androidTheme_notDynamic.png new file mode 100644 index 0000000000..ce2cdf8045 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButton_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_dynamic.png new file mode 100644 index 0000000000..ce2cdf8045 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..ce2cdf8045 Binary files /dev/null and b/core/designsystem/src/test/screenshots/IconButton/IconButton_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_1000.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_1000.png new file mode 100644 index 0000000000..450d55a097 Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_1000.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_115.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_115.png new file mode 100644 index 0000000000..6d023a207e Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_115.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_20.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_20.png new file mode 100644 index 0000000000..c125faccf6 Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_20.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_724.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_724.png new file mode 100644 index 0000000000..03bf6709ef Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_animation_724.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_androidTheme_notDynamic.png new file mode 100644 index 0000000000..cf35893fde Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_dynamic.png new file mode 100644 index 0000000000..7109265c77 Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..19265495c4 Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_androidTheme_notDynamic.png new file mode 100644 index 0000000000..156fc19832 Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_dynamic.png new file mode 100644 index 0000000000..e42f9855cd Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..89ea5e37c3 Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/LoadingWheel_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_androidTheme_notDynamic.png new file mode 100644 index 0000000000..ac0065cc7d Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_dynamic.png new file mode 100644 index 0000000000..41dbc1aea3 Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..2f1d9767cd Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_androidTheme_notDynamic.png new file mode 100644 index 0000000000..d90547cd85 Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_dynamic.png new file mode 100644 index 0000000000..1541e61330 Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..6949a89084 Binary files /dev/null and b/core/designsystem/src/test/screenshots/LoadingWheel/OverlayLoadingWheel_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_androidTheme_notDynamic.png new file mode 100644 index 0000000000..a698536d83 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_dynamic.png new file mode 100644 index 0000000000..01183397fa Binary files /dev/null and b/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..92317be34b Binary files /dev/null and b/core/designsystem/src/test/screenshots/Navigation/Navigation_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_fontScale2.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_fontScale2.png new file mode 100644 index 0000000000..a432cc93c5 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Navigation/Navigation_fontScale2.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_light_androidTheme_notDynamic.png new file mode 100644 index 0000000000..238b60c250 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Navigation/Navigation_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_dynamic.png new file mode 100644 index 0000000000..ff60eb5477 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..badd8e1c76 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Navigation/Navigation_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_androidTheme_notDynamic.png new file mode 100644 index 0000000000..bdf5d18f32 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_dynamic.png new file mode 100644 index 0000000000..dbfb08f1f4 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..074f3dc8c3 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tabs/Tabs_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_fontScale2.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_fontScale2.png new file mode 100644 index 0000000000..9a60923d93 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tabs/Tabs_fontScale2.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_light_androidTheme_notDynamic.png new file mode 100644 index 0000000000..5c38870dc1 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tabs/Tabs_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_dynamic.png new file mode 100644 index 0000000000..a11d826806 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..759641c934 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tabs/Tabs_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tag/Tag_dark_androidTheme_notDynamic.png new file mode 100644 index 0000000000..522dcd3014 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tag/Tag_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_dynamic.png new file mode 100644 index 0000000000..2d819edf7f Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..d6cfb48d0c Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tag/Tag_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_fontScale2.png b/core/designsystem/src/test/screenshots/Tag/Tag_fontScale2.png new file mode 100644 index 0000000000..fc66ddf58c Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tag/Tag_fontScale2.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tag/Tag_light_androidTheme_notDynamic.png new file mode 100644 index 0000000000..38ebe8b42f Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tag/Tag_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_dynamic.png new file mode 100644 index 0000000000..5683b4c6bc Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..53b1da2660 Binary files /dev/null and b/core/designsystem/src/test/screenshots/Tag/Tag_light_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_androidTheme_notDynamic.png new file mode 100644 index 0000000000..753c136055 Binary files /dev/null and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_dynamic.png new file mode 100644 index 0000000000..0e53746d9a Binary files /dev/null and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..1baa2362c3 Binary files /dev/null and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_dark_defaultTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_fontScale2.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_fontScale2.png new file mode 100644 index 0000000000..ed2f04eb15 Binary files /dev/null and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_fontScale2.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_androidTheme_notDynamic.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_androidTheme_notDynamic.png new file mode 100644 index 0000000000..7c0348b041 Binary files /dev/null and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_androidTheme_notDynamic.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_dynamic.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_dynamic.png new file mode 100644 index 0000000000..00e313d2b4 Binary files /dev/null and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_dynamic.png differ diff --git a/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_notDynamic.png b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_notDynamic.png new file mode 100644 index 0000000000..078378bea2 Binary files /dev/null and b/core/designsystem/src/test/screenshots/TopAppBar/TopAppBar_light_defaultTheme_notDynamic.png differ diff --git a/core/domain/build.gradle.kts b/core/domain/build.gradle.kts index 3c6c407e1c..b81d621026 100644 --- a/core/domain/build.gradle.kts +++ b/core/domain/build.gradle.kts @@ -14,8 +14,8 @@ * limitations under the License. */ plugins { - id("nowinandroid.android.library") - id("nowinandroid.android.library.jacoco") + alias(libs.plugins.nowinandroid.android.library) + alias(libs.plugins.nowinandroid.android.library.jacoco) id("com.google.devtools.ksp") } @@ -24,13 +24,13 @@ android { } dependencies { - implementation(project(":core:data")) - implementation(project(":core:model")) + implementation(projects.core.data) + implementation(projects.core.model) implementation(libs.hilt.android) implementation(libs.kotlinx.coroutines.android) implementation(libs.kotlinx.datetime) ksp(libs.hilt.compiler) - testImplementation(project(":core:testing")) + testImplementation(projects.core.testing) } \ No newline at end of file diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetFollowableTopicsUseCase.kt b/core/domain/src/main/kotlin/com/google/samples/apps/nowinandroid/core/domain/GetFollowableTopicsUseCase.kt similarity index 100% rename from core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetFollowableTopicsUseCase.kt rename to core/domain/src/main/kotlin/com/google/samples/apps/nowinandroid/core/domain/GetFollowableTopicsUseCase.kt diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetRecentSearchQueriesUseCase.kt b/core/domain/src/main/kotlin/com/google/samples/apps/nowinandroid/core/domain/GetRecentSearchQueriesUseCase.kt similarity index 100% rename from core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetRecentSearchQueriesUseCase.kt rename to core/domain/src/main/kotlin/com/google/samples/apps/nowinandroid/core/domain/GetRecentSearchQueriesUseCase.kt diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetSearchContentsCountUseCase.kt b/core/domain/src/main/kotlin/com/google/samples/apps/nowinandroid/core/domain/GetSearchContentsCountUseCase.kt similarity index 100% rename from core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetSearchContentsCountUseCase.kt rename to core/domain/src/main/kotlin/com/google/samples/apps/nowinandroid/core/domain/GetSearchContentsCountUseCase.kt diff --git a/core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetSearchContentsUseCase.kt b/core/domain/src/main/kotlin/com/google/samples/apps/nowinandroid/core/domain/GetSearchContentsUseCase.kt similarity index 100% rename from core/domain/src/main/java/com/google/samples/apps/nowinandroid/core/domain/GetSearchContentsUseCase.kt rename to core/domain/src/main/kotlin/com/google/samples/apps/nowinandroid/core/domain/GetSearchContentsUseCase.kt diff --git a/core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetFollowableTopicsUseCaseTest.kt b/core/domain/src/test/kotlin/com/google/samples/apps/nowinandroid/core/domain/GetFollowableTopicsUseCaseTest.kt similarity index 100% rename from core/domain/src/test/java/com/google/samples/apps/nowinandroid/core/domain/GetFollowableTopicsUseCaseTest.kt rename to core/domain/src/test/kotlin/com/google/samples/apps/nowinandroid/core/domain/GetFollowableTopicsUseCaseTest.kt diff --git a/core/model/build.gradle.kts b/core/model/build.gradle.kts index 55b49beb7f..393e3aa7d4 100644 --- a/core/model/build.gradle.kts +++ b/core/model/build.gradle.kts @@ -15,7 +15,7 @@ */ plugins { - id("nowinandroid.jvm.library") + alias(libs.plugins.nowinandroid.jvm.library) } dependencies { diff --git a/core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/DarkThemeConfig.kt b/core/model/src/main/kotlin/com/google/samples/apps/nowinandroid/core/model/data/DarkThemeConfig.kt similarity index 100% rename from core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/DarkThemeConfig.kt rename to core/model/src/main/kotlin/com/google/samples/apps/nowinandroid/core/model/data/DarkThemeConfig.kt diff --git a/core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/FollowableTopic.kt b/core/model/src/main/kotlin/com/google/samples/apps/nowinandroid/core/model/data/FollowableTopic.kt similarity index 100% rename from core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/FollowableTopic.kt rename to core/model/src/main/kotlin/com/google/samples/apps/nowinandroid/core/model/data/FollowableTopic.kt diff --git a/core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/NewsResource.kt b/core/model/src/main/kotlin/com/google/samples/apps/nowinandroid/core/model/data/NewsResource.kt similarity index 100% rename from core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/NewsResource.kt rename to core/model/src/main/kotlin/com/google/samples/apps/nowinandroid/core/model/data/NewsResource.kt diff --git a/core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/SearchResult.kt b/core/model/src/main/kotlin/com/google/samples/apps/nowinandroid/core/model/data/SearchResult.kt similarity index 100% rename from core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/SearchResult.kt rename to core/model/src/main/kotlin/com/google/samples/apps/nowinandroid/core/model/data/SearchResult.kt diff --git a/core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/ThemeBrand.kt b/core/model/src/main/kotlin/com/google/samples/apps/nowinandroid/core/model/data/ThemeBrand.kt similarity index 100% rename from core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/ThemeBrand.kt rename to core/model/src/main/kotlin/com/google/samples/apps/nowinandroid/core/model/data/ThemeBrand.kt diff --git a/core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/Topic.kt b/core/model/src/main/kotlin/com/google/samples/apps/nowinandroid/core/model/data/Topic.kt similarity index 100% rename from core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/Topic.kt rename to core/model/src/main/kotlin/com/google/samples/apps/nowinandroid/core/model/data/Topic.kt diff --git a/core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/UserData.kt b/core/model/src/main/kotlin/com/google/samples/apps/nowinandroid/core/model/data/UserData.kt similarity index 100% rename from core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/UserData.kt rename to core/model/src/main/kotlin/com/google/samples/apps/nowinandroid/core/model/data/UserData.kt diff --git a/core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/UserNewsResource.kt b/core/model/src/main/kotlin/com/google/samples/apps/nowinandroid/core/model/data/UserNewsResource.kt similarity index 100% rename from core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/UserNewsResource.kt rename to core/model/src/main/kotlin/com/google/samples/apps/nowinandroid/core/model/data/UserNewsResource.kt diff --git a/core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/UserSearchResult.kt b/core/model/src/main/kotlin/com/google/samples/apps/nowinandroid/core/model/data/UserSearchResult.kt similarity index 100% rename from core/model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/UserSearchResult.kt rename to core/model/src/main/kotlin/com/google/samples/apps/nowinandroid/core/model/data/UserSearchResult.kt diff --git a/core/network/build.gradle.kts b/core/network/build.gradle.kts index 633e2573d8..dce97031f7 100644 --- a/core/network/build.gradle.kts +++ b/core/network/build.gradle.kts @@ -15,9 +15,9 @@ */ plugins { - id("nowinandroid.android.library") - id("nowinandroid.android.library.jacoco") - id("nowinandroid.android.hilt") + alias(libs.plugins.nowinandroid.android.library) + alias(libs.plugins.nowinandroid.android.library.jacoco) + alias(libs.plugins.nowinandroid.android.hilt) id("kotlinx-serialization") id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin") } @@ -39,8 +39,8 @@ secrets { } dependencies { - implementation(project(":core:common")) - implementation(project(":core:model")) + implementation(projects.core.common) + implementation(projects.core.model) implementation(libs.coil.kt) implementation(libs.coil.kt.svg) implementation(libs.kotlinx.coroutines.android) @@ -50,5 +50,5 @@ dependencies { implementation(libs.retrofit.core) implementation(libs.retrofit.kotlin.serialization) - testImplementation(project(":core:testing")) + testImplementation(projects.core.testing) } diff --git a/core/network/src/demo/java/com/google/samples/apps/nowinandroid/core/network/di/FlavoredNetworkModule.kt b/core/network/src/demo/kotlin/com/google/samples/apps/nowinandroid/core/network/di/FlavoredNetworkModule.kt similarity index 93% rename from core/network/src/demo/java/com/google/samples/apps/nowinandroid/core/network/di/FlavoredNetworkModule.kt rename to core/network/src/demo/kotlin/com/google/samples/apps/nowinandroid/core/network/di/FlavoredNetworkModule.kt index 6d8a668cf8..a6162a9cc7 100644 --- a/core/network/src/demo/java/com/google/samples/apps/nowinandroid/core/network/di/FlavoredNetworkModule.kt +++ b/core/network/src/demo/kotlin/com/google/samples/apps/nowinandroid/core/network/di/FlavoredNetworkModule.kt @@ -28,5 +28,5 @@ import dagger.hilt.components.SingletonComponent interface FlavoredNetworkModule { @Binds - fun binds(it: FakeNiaNetworkDataSource): NiaNetworkDataSource + fun binds(impl: FakeNiaNetworkDataSource): NiaNetworkDataSource } diff --git a/core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/util/InstantSerializer.kt b/core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/util/InstantSerializer.kt deleted file mode 100644 index dec73dc107..0000000000 --- a/core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/util/InstantSerializer.kt +++ /dev/null @@ -1,39 +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.network.model.util - -import kotlinx.datetime.Instant -import kotlinx.datetime.toInstant -import kotlinx.serialization.KSerializer -import kotlinx.serialization.descriptors.PrimitiveKind.STRING -import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder - -object InstantSerializer : KSerializer { - override fun deserialize(decoder: Decoder): Instant = - decoder.decodeString().toInstant() - - override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor( - serialName = "Instant", - kind = STRING, - ) - - override fun serialize(encoder: Encoder, value: Instant) = - encoder.encodeString(value.toString()) -} diff --git a/core/network/src/main/java/JvmUnitTestFakeAssetManager.kt b/core/network/src/main/kotlin/JvmUnitTestFakeAssetManager.kt similarity index 100% rename from core/network/src/main/java/JvmUnitTestFakeAssetManager.kt rename to core/network/src/main/kotlin/JvmUnitTestFakeAssetManager.kt diff --git a/core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/NiaNetworkDataSource.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/NiaNetworkDataSource.kt similarity index 100% rename from core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/NiaNetworkDataSource.kt rename to core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/NiaNetworkDataSource.kt diff --git a/core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/di/NetworkModule.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/NetworkModule.kt similarity index 100% rename from core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/di/NetworkModule.kt rename to core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/NetworkModule.kt diff --git a/core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeAssetManager.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/fake/FakeAssetManager.kt similarity index 100% rename from core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeAssetManager.kt rename to core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/fake/FakeAssetManager.kt diff --git a/core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeNiaNetworkDataSource.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/fake/FakeNiaNetworkDataSource.kt similarity index 100% rename from core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeNiaNetworkDataSource.kt rename to core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/fake/FakeNiaNetworkDataSource.kt diff --git a/core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkChangeList.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/model/NetworkChangeList.kt similarity index 100% rename from core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkChangeList.kt rename to core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/model/NetworkChangeList.kt diff --git a/core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkNewsResource.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/model/NetworkNewsResource.kt similarity index 89% rename from core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkNewsResource.kt rename to core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/model/NetworkNewsResource.kt index 42fbfa826a..89af19c990 100644 --- a/core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkNewsResource.kt +++ b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/model/NetworkNewsResource.kt @@ -17,7 +17,6 @@ package com.google.samples.apps.nowinandroid.core.network.model import com.google.samples.apps.nowinandroid.core.model.data.NewsResource -import com.google.samples.apps.nowinandroid.core.network.model.util.InstantSerializer import kotlinx.datetime.Instant import kotlinx.serialization.Serializable @@ -31,7 +30,6 @@ data class NetworkNewsResource( val content: String, val url: String, val headerImageUrl: String, - @Serializable(InstantSerializer::class) val publishDate: Instant, val type: String, val topics: List = listOf(), @@ -47,7 +45,6 @@ data class NetworkNewsResourceExpanded( val content: String, val url: String, val headerImageUrl: String, - @Serializable(InstantSerializer::class) val publishDate: Instant, val type: String, val topics: List = listOf(), diff --git a/core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkTopic.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/model/NetworkTopic.kt similarity index 100% rename from core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/model/NetworkTopic.kt rename to core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/model/NetworkTopic.kt diff --git a/core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/retrofit/RetrofitNiaNetwork.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/retrofit/RetrofitNiaNetwork.kt similarity index 100% rename from core/network/src/main/java/com/google/samples/apps/nowinandroid/core/network/retrofit/RetrofitNiaNetwork.kt rename to core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/retrofit/RetrofitNiaNetwork.kt diff --git a/core/network/src/prod/java/com/google/samples/apps/nowinandroid/core/network/di/FlavoredNetworkModule.kt b/core/network/src/prod/kotlin/com/google/samples/apps/nowinandroid/core/network/di/FlavoredNetworkModule.kt similarity index 94% rename from core/network/src/prod/java/com/google/samples/apps/nowinandroid/core/network/di/FlavoredNetworkModule.kt rename to core/network/src/prod/kotlin/com/google/samples/apps/nowinandroid/core/network/di/FlavoredNetworkModule.kt index 7b116b6714..51a8a6f19f 100644 --- a/core/network/src/prod/java/com/google/samples/apps/nowinandroid/core/network/di/FlavoredNetworkModule.kt +++ b/core/network/src/prod/kotlin/com/google/samples/apps/nowinandroid/core/network/di/FlavoredNetworkModule.kt @@ -28,5 +28,5 @@ import dagger.hilt.components.SingletonComponent interface FlavoredNetworkModule { @Binds - fun binds(it: RetrofitNiaNetwork): NiaNetworkDataSource + fun binds(impl: RetrofitNiaNetwork): NiaNetworkDataSource } diff --git a/core/network/src/test/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeNiaNetworkDataSourceTest.kt b/core/network/src/test/kotlin/com/google/samples/apps/nowinandroid/core/network/fake/FakeNiaNetworkDataSourceTest.kt similarity index 100% rename from core/network/src/test/java/com/google/samples/apps/nowinandroid/core/network/fake/FakeNiaNetworkDataSourceTest.kt rename to core/network/src/test/kotlin/com/google/samples/apps/nowinandroid/core/network/fake/FakeNiaNetworkDataSourceTest.kt diff --git a/core/notifications/build.gradle.kts b/core/notifications/build.gradle.kts index 012c6f3f36..31b15a805a 100644 --- a/core/notifications/build.gradle.kts +++ b/core/notifications/build.gradle.kts @@ -14,9 +14,9 @@ * limitations under the License. */ plugins { - id("nowinandroid.android.library") - id("nowinandroid.android.library.compose") - id("nowinandroid.android.hilt") + alias(libs.plugins.nowinandroid.android.library) + alias(libs.plugins.nowinandroid.android.library.compose) + alias(libs.plugins.nowinandroid.android.hilt) } android { @@ -24,8 +24,8 @@ android { } dependencies { - implementation(project(":core:common")) - implementation(project(":core:model")) + implementation(projects.core.common) + implementation(projects.core.model) implementation(libs.kotlinx.coroutines.android) implementation(libs.androidx.browser) diff --git a/core/notifications/src/demo/java/com/google/samples/apps/nowinandroid/core/notifications/NotificationsModule.kt b/core/notifications/src/demo/kotlin/com/google/samples/apps/nowinandroid/core/notifications/NotificationsModule.kt similarity index 100% rename from core/notifications/src/demo/java/com/google/samples/apps/nowinandroid/core/notifications/NotificationsModule.kt rename to core/notifications/src/demo/kotlin/com/google/samples/apps/nowinandroid/core/notifications/NotificationsModule.kt diff --git a/core/notifications/src/main/java/com/google/samples/apps/nowinandroid/core/notifications/NoOpNotifier.kt b/core/notifications/src/main/kotlin/com/google/samples/apps/nowinandroid/core/notifications/NoOpNotifier.kt similarity index 100% rename from core/notifications/src/main/java/com/google/samples/apps/nowinandroid/core/notifications/NoOpNotifier.kt rename to core/notifications/src/main/kotlin/com/google/samples/apps/nowinandroid/core/notifications/NoOpNotifier.kt diff --git a/core/notifications/src/main/java/com/google/samples/apps/nowinandroid/core/notifications/Notifier.kt b/core/notifications/src/main/kotlin/com/google/samples/apps/nowinandroid/core/notifications/Notifier.kt similarity index 100% rename from core/notifications/src/main/java/com/google/samples/apps/nowinandroid/core/notifications/Notifier.kt rename to core/notifications/src/main/kotlin/com/google/samples/apps/nowinandroid/core/notifications/Notifier.kt diff --git a/core/notifications/src/main/java/com/google/samples/apps/nowinandroid/core/notifications/SystemTrayNotifier.kt b/core/notifications/src/main/kotlin/com/google/samples/apps/nowinandroid/core/notifications/SystemTrayNotifier.kt similarity index 98% rename from core/notifications/src/main/java/com/google/samples/apps/nowinandroid/core/notifications/SystemTrayNotifier.kt rename to core/notifications/src/main/kotlin/com/google/samples/apps/nowinandroid/core/notifications/SystemTrayNotifier.kt index b7fcc9b263..7e74f819c2 100644 --- a/core/notifications/src/main/java/com/google/samples/apps/nowinandroid/core/notifications/SystemTrayNotifier.kt +++ b/core/notifications/src/main/kotlin/com/google/samples/apps/nowinandroid/core/notifications/SystemTrayNotifier.kt @@ -141,7 +141,7 @@ private fun Context.createNewsNotification( } /** - * Ensures the a notification channel is is present if applicable + * Ensures that a notification channel is present if applicable */ private fun Context.ensureNotificationChannelExists() { if (VERSION.SDK_INT < VERSION_CODES.O) return diff --git a/core/notifications/src/prod/java/com/google/samples/apps/nowinandroid/core/notifications/NotificationsModule.kt b/core/notifications/src/prod/kotlin/com/google/samples/apps/nowinandroid/core/notifications/NotificationsModule.kt similarity index 100% rename from core/notifications/src/prod/java/com/google/samples/apps/nowinandroid/core/notifications/NotificationsModule.kt rename to core/notifications/src/prod/kotlin/com/google/samples/apps/nowinandroid/core/notifications/NotificationsModule.kt diff --git a/core/testing/build.gradle.kts b/core/testing/build.gradle.kts index 6cba0086de..8ad91a0d58 100644 --- a/core/testing/build.gradle.kts +++ b/core/testing/build.gradle.kts @@ -14,9 +14,9 @@ * limitations under the License. */ plugins { - id("nowinandroid.android.library") - id("nowinandroid.android.library.compose") - id("nowinandroid.android.hilt") + alias(libs.plugins.nowinandroid.android.library) + alias(libs.plugins.nowinandroid.android.library.compose) + alias(libs.plugins.nowinandroid.android.hilt) } android { @@ -40,11 +40,12 @@ dependencies { debugApi(libs.androidx.compose.ui.testManifest) - implementation(project(":core:common")) - implementation(project(":core:data")) - implementation(project(":core:domain")) - implementation(project(":core:model")) - implementation(project(":core:notifications")) - implementation(project(":core:analytics")) + implementation(projects.core.common) + implementation(projects.core.data) + implementation(projects.core.designsystem) + implementation(projects.core.domain) + implementation(projects.core.model) + implementation(projects.core.notifications) + implementation(projects.core.analytics) implementation(libs.kotlinx.datetime) } diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/util/ScreenshotHelper.kt b/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/util/ScreenshotHelper.kt deleted file mode 100644 index e0756d16dc..0000000000 --- a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/util/ScreenshotHelper.kt +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2023 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 androidx.activity.ComponentActivity -import androidx.activity.compose.setContent -import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.ui.platform.LocalInspectionMode -import androidx.compose.ui.test.junit4.AndroidComposeTestRule -import androidx.compose.ui.test.onRoot -import androidx.test.ext.junit.rules.ActivityScenarioRule -import com.github.takahirom.roborazzi.RoborazziOptions -import com.github.takahirom.roborazzi.RoborazziOptions.CompareOptions -import com.github.takahirom.roborazzi.RoborazziOptions.RecordOptions -import com.github.takahirom.roborazzi.captureRoboImage -import org.robolectric.RuntimeEnvironment - -val DefaultRoborazziOptions = - RoborazziOptions( - compareOptions = CompareOptions(changeThreshold = 0f), // Pixel-perfect matching - recordOptions = RecordOptions(resizeScale = 0.5), // Reduce the size of the PNGs - ) - -fun AndroidComposeTestRule, A>.captureMultiDevice( - screenshotName: String, - body: @Composable () -> Unit, -) { - listOf( - "phone" to "spec:shape=Normal,width=640,height=360,unit=dp,dpi=480", - "foldable" to "spec:shape=Normal,width=673,height=841,unit=dp,dpi=480", - "tablet" to "spec:shape=Normal,width=1280,height=800,unit=dp,dpi=480", - ).forEach { - this.captureForDevice(it.first, it.second, screenshotName, body) - } -} - -fun AndroidComposeTestRule, A>.captureForDevice( - deviceName: String, - deviceSpec: String, - screenshotName: String, - body: @Composable () -> Unit, - roborazziOptions: RoborazziOptions = DefaultRoborazziOptions, -) { - val (width, height, dpi) = extractSpecs(deviceSpec) - - // Set qualifiers from specs - RuntimeEnvironment.setQualifiers("w${width}dp-h${height}dp-${dpi}dpi") - - this.activity.setContent { - CompositionLocalProvider( - LocalInspectionMode provides true, - ) { - body() - } - } - this.onRoot() - .captureRoboImage( - "src/test/screenshots/${screenshotName}_$deviceName.png", - roborazziOptions = roborazziOptions, - ) -} - -/** - * Extracts some properties from the spec string. Note that this function is not exhaustive. - */ -private fun extractSpecs(deviceSpec: String): TestDeviceSpecs { - val specs = deviceSpec.substringAfter("spec:") - .split(",").map { it.split("=") }.associate { it[0] to it[1] } - val width = specs["width"]?.toInt() ?: 640 - val height = specs["height"]?.toInt() ?: 480 - val dpi = specs["dpi"]?.toInt() ?: 480 - return TestDeviceSpecs(width, height, dpi) -} - -data class TestDeviceSpecs(val width: Int, val height: Int, val dpi: Int) diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/rules/GrantPostNotificationsPermissionRule.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/rules/GrantPostNotificationsPermissionRule.kt similarity index 100% rename from core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/rules/GrantPostNotificationsPermissionRule.kt rename to core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/rules/GrantPostNotificationsPermissionRule.kt diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/NiaTestRunner.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/NiaTestRunner.kt similarity index 100% rename from core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/NiaTestRunner.kt rename to core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/NiaTestRunner.kt diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/data/FollowableTopicTestData.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/data/FollowableTopicTestData.kt similarity index 100% rename from core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/data/FollowableTopicTestData.kt rename to core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/data/FollowableTopicTestData.kt diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/data/NewsResourcesTestData.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/data/NewsResourcesTestData.kt similarity index 100% rename from core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/data/NewsResourcesTestData.kt rename to core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/data/NewsResourcesTestData.kt diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/data/TopicsTestData.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/data/TopicsTestData.kt similarity index 100% rename from core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/data/TopicsTestData.kt rename to core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/data/TopicsTestData.kt diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/data/UserNewsResourcesTestData.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/data/UserNewsResourcesTestData.kt similarity index 100% rename from core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/data/UserNewsResourcesTestData.kt rename to core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/data/UserNewsResourcesTestData.kt diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/di/TestDispatcherModule.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/di/TestDispatcherModule.kt similarity index 100% rename from core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/di/TestDispatcherModule.kt rename to core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/di/TestDispatcherModule.kt diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/di/TestDispatchersModule.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/di/TestDispatchersModule.kt similarity index 100% rename from core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/di/TestDispatchersModule.kt rename to core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/di/TestDispatchersModule.kt diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/notifications/TestNotifier.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/notifications/TestNotifier.kt similarity index 100% rename from core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/notifications/TestNotifier.kt rename to core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/notifications/TestNotifier.kt diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestNewsRepository.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestNewsRepository.kt similarity index 100% rename from core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestNewsRepository.kt rename to core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestNewsRepository.kt diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestRecentSearchRepository.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestRecentSearchRepository.kt similarity index 100% rename from core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestRecentSearchRepository.kt rename to core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestRecentSearchRepository.kt diff --git a/core/testing/src/main/java/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 similarity index 100% rename from core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt rename to core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestTopicsRepository.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestTopicsRepository.kt similarity index 100% rename from core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestTopicsRepository.kt rename to core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestTopicsRepository.kt diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestUserDataRepository.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestUserDataRepository.kt similarity index 97% rename from core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestUserDataRepository.kt rename to core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestUserDataRepository.kt index 9d1650c989..504e792170 100644 --- a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/repository/TestUserDataRepository.kt +++ b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestUserDataRepository.kt @@ -49,7 +49,7 @@ class TestUserDataRepository : UserDataRepository { _userData.tryEmit(currentUserData.copy(followedTopics = followedTopicIds)) } - override suspend fun toggleFollowedTopicId(followedTopicId: String, followed: Boolean) { + override suspend fun setTopicIdFollowed(followedTopicId: String, followed: Boolean) { currentUserData.let { current -> val followedTopics = if (followed) { current.followedTopics + followedTopicId diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/util/MainDispatcherRule.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/MainDispatcherRule.kt similarity index 94% rename from core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/util/MainDispatcherRule.kt rename to core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/MainDispatcherRule.kt index 5b8807b753..28155f5ad5 100644 --- a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/util/MainDispatcherRule.kt +++ b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/MainDispatcherRule.kt @@ -30,7 +30,7 @@ import org.junit.runner.Description * for the duration of the test. */ class MainDispatcherRule( - val testDispatcher: TestDispatcher = UnconfinedTestDispatcher(), + private val testDispatcher: TestDispatcher = UnconfinedTestDispatcher(), ) : TestWatcher() { override fun starting(description: Description) { Dispatchers.setMain(testDispatcher) diff --git a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/ScreenshotHelper.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/ScreenshotHelper.kt new file mode 100644 index 0000000000..e84fe7d330 --- /dev/null +++ b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/ScreenshotHelper.kt @@ -0,0 +1,207 @@ +/* + * Copyright 2023 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 androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.getValue +import androidx.compose.runtime.key +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.ui.platform.LocalInspectionMode +import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.compose.ui.test.onRoot +import androidx.test.ext.junit.rules.ActivityScenarioRule +import com.github.takahirom.roborazzi.RoborazziOptions +import com.github.takahirom.roborazzi.RoborazziOptions.CompareOptions +import com.github.takahirom.roborazzi.RoborazziOptions.RecordOptions +import com.github.takahirom.roborazzi.captureRoboImage +import com.google.accompanist.testharness.TestHarness +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme +import org.robolectric.RuntimeEnvironment + +val DefaultRoborazziOptions = + RoborazziOptions( + compareOptions = CompareOptions(changeThreshold = 0f), // Pixel-perfect matching + recordOptions = RecordOptions(resizeScale = 0.5), // Reduce the size of the PNGs + ) + +enum class DefaultTestDevices(val description: String, val spec: String) { + PHONE("phone", "spec:shape=Normal,width=640,height=360,unit=dp,dpi=480"), + FOLDABLE("foldable", "spec:shape=Normal,width=673,height=841,unit=dp,dpi=480"), + TABLET("tablet", "spec:shape=Normal,width=1280,height=800,unit=dp,dpi=480"), +} +fun AndroidComposeTestRule, A>.captureMultiDevice( + screenshotName: String, + body: @Composable () -> Unit, +) { + DefaultTestDevices.values().forEach { + this.captureForDevice(it.description, it.spec, screenshotName, body = body) + } +} + +fun AndroidComposeTestRule, A>.captureForDevice( + deviceName: String, + deviceSpec: String, + screenshotName: String, + roborazziOptions: RoborazziOptions = DefaultRoborazziOptions, + darkMode: Boolean = false, + body: @Composable () -> Unit, +) { + val (width, height, dpi) = extractSpecs(deviceSpec) + + // Set qualifiers from specs + RuntimeEnvironment.setQualifiers("w${width}dp-h${height}dp-${dpi}dpi") + + this.activity.setContent { + CompositionLocalProvider( + LocalInspectionMode provides true, + ) { + TestHarness(darkMode = darkMode) { + body() + } + } + } + this.onRoot() + .captureRoboImage( + "src/test/screenshots/${screenshotName}_$deviceName.png", + roborazziOptions = roborazziOptions, + ) +} + +/** + * Takes six screenshots combining light/dark and default/Android themes and whether dynamic color + * is enabled. + */ +fun AndroidComposeTestRule, A>.captureMultiTheme( + name: String, + overrideFileName: String? = null, + shouldCompareDarkMode: Boolean = true, + shouldCompareDynamicColor: Boolean = true, + shouldCompareAndroidTheme: Boolean = true, + content: @Composable (desc: String) -> Unit, +) { + val darkModeValues = if (shouldCompareDarkMode) listOf(true, false) else listOf(false) + val dynamicThemingValues = if (shouldCompareDynamicColor) listOf(true, false) else listOf(false) + val androidThemeValues = if (shouldCompareAndroidTheme) listOf(true, false) else listOf(false) + + var darkMode by mutableStateOf(true) + var dynamicTheming by mutableStateOf(false) + var androidTheme by mutableStateOf(false) + + this.setContent { + CompositionLocalProvider( + LocalInspectionMode provides true, + ) { + NiaTheme( + androidTheme = androidTheme, + darkTheme = darkMode, + disableDynamicTheming = !dynamicTheming, + ) { + // Keying is necessary in some cases (e.g. animations) + key(androidTheme, darkMode, dynamicTheming) { + val description = generateDescription( + shouldCompareDarkMode, + darkMode, + shouldCompareAndroidTheme, + androidTheme, + shouldCompareDynamicColor, + dynamicTheming, + ) + content(description) + } + } + } + } + + // Create permutations + darkModeValues.forEach { isDarkMode -> + darkMode = isDarkMode + val darkModeDesc = if (isDarkMode) "dark" else "light" + + androidThemeValues.forEach { isAndroidTheme -> + androidTheme = isAndroidTheme + val androidThemeDesc = if (isAndroidTheme) "androidTheme" else "defaultTheme" + + dynamicThemingValues.forEach dynamicTheme@{ isDynamicTheming -> + // Skip tests with both Android Theme and Dynamic color as they're incompatible. + if (isAndroidTheme && isDynamicTheming) return@dynamicTheme + + dynamicTheming = isDynamicTheming + val dynamicThemingDesc = if (isDynamicTheming) "dynamic" else "notDynamic" + + val filename = overrideFileName ?: name + + this.onRoot() + .captureRoboImage( + "src/test/screenshots/" + + "$name/$filename" + + "_$darkModeDesc" + + "_$androidThemeDesc" + + "_$dynamicThemingDesc" + + ".png", + roborazziOptions = DefaultRoborazziOptions, + ) + } + } + } +} + +@Composable +private fun generateDescription( + shouldCompareDarkMode: Boolean, + darkMode: Boolean, + shouldCompareAndroidTheme: Boolean, + androidTheme: Boolean, + shouldCompareDynamicColor: Boolean, + dynamicTheming: Boolean, +): String { + val description = "" + + if (shouldCompareDarkMode) { + if (darkMode) "Dark" else "Light" + } else { + "" + } + + if (shouldCompareAndroidTheme) { + if (androidTheme) " Android" else " Default" + } else { + "" + } + + if (shouldCompareDynamicColor) { + if (dynamicTheming) " Dynamic" else "" + } else { + "" + } + + return description.trim() +} + +/** + * Extracts some properties from the spec string. Note that this function is not exhaustive. + */ +private fun extractSpecs(deviceSpec: String): TestDeviceSpecs { + val specs = deviceSpec.substringAfter("spec:") + .split(",").map { it.split("=") }.associate { it[0] to it[1] } + val width = specs["width"]?.toInt() ?: 640 + val height = specs["height"]?.toInt() ?: 480 + val dpi = specs["dpi"]?.toInt() ?: 480 + return TestDeviceSpecs(width, height, dpi) +} + +data class TestDeviceSpecs(val width: Int, val height: Int, val dpi: Int) diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/util/TestAnalyticsHelper.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/TestAnalyticsHelper.kt similarity index 100% rename from core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/util/TestAnalyticsHelper.kt rename to core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/TestAnalyticsHelper.kt diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/util/TestNetworkMonitor.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/TestNetworkMonitor.kt similarity index 100% rename from core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/util/TestNetworkMonitor.kt rename to core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/TestNetworkMonitor.kt diff --git a/core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/util/TestSyncManager.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/TestSyncManager.kt similarity index 100% rename from core/testing/src/main/java/com/google/samples/apps/nowinandroid/core/testing/util/TestSyncManager.kt rename to core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/util/TestSyncManager.kt diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts index 044abedaf8..c9527d09ec 100644 --- a/core/ui/build.gradle.kts +++ b/core/ui/build.gradle.kts @@ -14,9 +14,9 @@ * limitations under the License. */ plugins { - id("nowinandroid.android.library") - id("nowinandroid.android.library.compose") - id("nowinandroid.android.library.jacoco") + alias(libs.plugins.nowinandroid.android.library) + alias(libs.plugins.nowinandroid.android.library.compose) + alias(libs.plugins.nowinandroid.android.library.jacoco) } android { @@ -40,10 +40,10 @@ dependencies { debugApi(libs.androidx.compose.ui.tooling) - implementation(project(":core:analytics")) - implementation(project(":core:designsystem")) - implementation(project(":core:domain")) - implementation(project(":core:model")) + implementation(projects.core.analytics) + implementation(projects.core.designsystem) + implementation(projects.core.domain) + implementation(projects.core.model) implementation(libs.androidx.activity.compose) implementation(libs.androidx.browser) implementation(libs.androidx.core.ktx) @@ -51,5 +51,5 @@ dependencies { implementation(libs.coil.kt.compose) implementation(libs.kotlinx.datetime) - androidTestImplementation(project(":core:testing")) + androidTestImplementation(projects.core.testing) } diff --git a/core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt b/core/ui/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt similarity index 100% rename from core/ui/src/androidTest/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt rename to core/ui/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardTest.kt diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/AnalyticsExtensions.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/AnalyticsExtensions.kt similarity index 100% rename from core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/AnalyticsExtensions.kt rename to core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/AnalyticsExtensions.kt diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/DevicePreviews.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/DevicePreviews.kt similarity index 100% rename from core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/DevicePreviews.kt rename to core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/DevicePreviews.kt diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/FollowableTopicPreviewParameterProvider.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/FollowableTopicPreviewParameterProvider.kt similarity index 100% rename from core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/FollowableTopicPreviewParameterProvider.kt rename to core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/FollowableTopicPreviewParameterProvider.kt diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/JankStatsExtensions.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/JankStatsExtensions.kt similarity index 100% rename from core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/JankStatsExtensions.kt rename to core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/JankStatsExtensions.kt diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt similarity index 87% rename from core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt rename to core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt index 4a9f5d7c9a..e2904afc35 100644 --- a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt +++ b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt @@ -21,12 +21,13 @@ import android.net.Uri import androidx.annotation.ColorInt import androidx.browser.customtabs.CustomTabColorSchemeParams import androidx.browser.customtabs.CustomTabsIntent +import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyListScope -import androidx.compose.foundation.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.LazyGridScope -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.foundation.lazy.grid.items +import androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridScope +import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid +import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells +import androidx.compose.foundation.lazy.staggeredgrid.items import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -47,7 +48,8 @@ import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource * An extension on [LazyListScope] defining a feed with news resources. * Depending on the [feedState], this might emit no items. */ -fun LazyGridScope.newsFeed( +@OptIn(ExperimentalFoundationApi::class) +fun LazyStaggeredGridScope.newsFeed( feedState: NewsFeedUiState, onNewsResourcesCheckedChanged: (String, Boolean) -> Unit, onNewsResourceViewed: (String) -> Unit, @@ -88,7 +90,9 @@ fun LazyGridScope.newsFeed( ) }, onTopicClick = onTopicClick, - modifier = Modifier.padding(horizontal = 8.dp), + modifier = Modifier + .padding(horizontal = 8.dp) + .animateItemPlacement(), ) } } @@ -129,7 +133,7 @@ sealed interface NewsFeedUiState { @Composable private fun NewsFeedLoadingPreview() { NiaTheme { - LazyVerticalGrid(columns = GridCells.Adaptive(300.dp)) { + LazyVerticalStaggeredGrid(columns = StaggeredGridCells.Adaptive(300.dp)) { newsFeed( feedState = NewsFeedUiState.Loading, onNewsResourcesCheckedChanged = { _, _ -> }, @@ -148,7 +152,7 @@ private fun NewsFeedContentPreview( userNewsResources: List, ) { NiaTheme { - LazyVerticalGrid(columns = GridCells.Adaptive(300.dp)) { + LazyVerticalStaggeredGrid(columns = StaggeredGridCells.Adaptive(300.dp)) { newsFeed( feedState = NewsFeedUiState.Success(userNewsResources), onNewsResourcesCheckedChanged = { _, _ -> }, diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt similarity index 100% rename from core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt rename to core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt similarity index 100% rename from core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt rename to core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCardList.kt diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/TimeZoneBroadcastReceiver.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/TimeZoneBroadcastReceiver.kt similarity index 100% rename from core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/TimeZoneBroadcastReceiver.kt rename to core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/TimeZoneBroadcastReceiver.kt diff --git a/core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/UserNewsResourcePreviewParameterProvider.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/UserNewsResourcePreviewParameterProvider.kt similarity index 100% rename from core/ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/UserNewsResourcePreviewParameterProvider.kt rename to core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/UserNewsResourcePreviewParameterProvider.kt diff --git a/feature/bookmarks/build.gradle.kts b/feature/bookmarks/build.gradle.kts index 667e674ec3..32394f9119 100644 --- a/feature/bookmarks/build.gradle.kts +++ b/feature/bookmarks/build.gradle.kts @@ -15,9 +15,9 @@ */ plugins { - id("nowinandroid.android.feature") - id("nowinandroid.android.library.compose") - id("nowinandroid.android.library.jacoco") + alias(libs.plugins.nowinandroid.android.feature) + alias(libs.plugins.nowinandroid.android.library.compose) + alias(libs.plugins.nowinandroid.android.library.jacoco) } android { diff --git a/feature/bookmarks/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt b/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt similarity index 100% rename from feature/bookmarks/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt rename to feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt diff --git a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt b/feature/bookmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt similarity index 94% rename from feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt rename to feature/bookmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt index e46ada0154..7d51c6e84e 100644 --- a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt +++ b/feature/bookmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt @@ -35,10 +35,10 @@ import androidx.compose.foundation.layout.systemBars import androidx.compose.foundation.layout.windowInsetsBottomHeight import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.foundation.lazy.grid.GridCells.Adaptive -import androidx.compose.foundation.lazy.grid.GridItemSpan -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.foundation.lazy.grid.rememberLazyGridState +import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid +import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells +import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan +import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -175,17 +175,17 @@ private fun BookmarksGrid( onTopicClick: (String) -> Unit, modifier: Modifier = Modifier, ) { - val scrollableState = rememberLazyGridState() + val scrollableState = rememberLazyStaggeredGridState() TrackScrollJank(scrollableState = scrollableState, stateName = "bookmarks:grid") Box( modifier = modifier .fillMaxSize(), ) { - LazyVerticalGrid( - columns = Adaptive(300.dp), + LazyVerticalStaggeredGrid( + columns = StaggeredGridCells.Adaptive(300.dp), contentPadding = PaddingValues(16.dp), horizontalArrangement = Arrangement.spacedBy(16.dp), - verticalArrangement = Arrangement.spacedBy(24.dp), + verticalItemSpacing = 24.dp, state = scrollableState, modifier = Modifier .fillMaxSize() @@ -197,7 +197,7 @@ private fun BookmarksGrid( onNewsResourceViewed = onNewsResourceViewed, onTopicClick = onTopicClick, ) - item(span = { GridItemSpan(maxLineSpan) }) { + item(span = StaggeredGridItemSpan.FullLine) { Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.safeDrawing)) } } diff --git a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt b/feature/bookmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt similarity index 100% rename from feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt rename to feature/bookmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModel.kt diff --git a/feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/navigation/BookmarksNavigation.kt b/feature/bookmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/navigation/BookmarksNavigation.kt similarity index 100% rename from feature/bookmarks/src/main/java/com/google/samples/apps/nowinandroid/feature/bookmarks/navigation/BookmarksNavigation.kt rename to feature/bookmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/navigation/BookmarksNavigation.kt diff --git a/feature/bookmarks/src/test/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt b/feature/bookmarks/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt similarity index 100% rename from feature/bookmarks/src/test/java/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt rename to feature/bookmarks/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt diff --git a/feature/foryou/build.gradle.kts b/feature/foryou/build.gradle.kts index bd633e3d2c..afe769ab8c 100644 --- a/feature/foryou/build.gradle.kts +++ b/feature/foryou/build.gradle.kts @@ -15,9 +15,9 @@ */ plugins { - id("nowinandroid.android.feature") - id("nowinandroid.android.library.compose") - id("nowinandroid.android.library.jacoco") + alias(libs.plugins.nowinandroid.android.feature) + alias(libs.plugins.nowinandroid.android.library.compose) + alias(libs.plugins.nowinandroid.android.library.jacoco) } android { diff --git a/feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt b/feature/foryou/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt similarity index 100% rename from feature/foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt rename to feature/foryou/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt diff --git a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt b/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt similarity index 96% rename from feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt rename to feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt index a24a91f1ab..65b5ecbc44 100644 --- a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt +++ b/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt @@ -49,13 +49,14 @@ import androidx.compose.foundation.layout.windowInsetsBottomHeight import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.GridCells.Adaptive -import androidx.compose.foundation.lazy.grid.GridItemSpan -import androidx.compose.foundation.lazy.grid.LazyGridScope import androidx.compose.foundation.lazy.grid.LazyHorizontalGrid -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.lazy.grid.rememberLazyGridState +import androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridScope +import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid +import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells +import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan +import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState import androidx.compose.foundation.shape.CornerSize import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Icon @@ -153,7 +154,7 @@ internal fun ForYouScreen( val itemsAvailable = feedItemsSize(feedState, onboardingUiState) - val state = rememberLazyGridState() + val state = rememberLazyStaggeredGridState() val scrollbarState = state.scrollbarState( itemsAvailable = itemsAvailable, ) @@ -163,11 +164,11 @@ internal fun ForYouScreen( modifier = modifier .fillMaxSize(), ) { - LazyVerticalGrid( - columns = Adaptive(300.dp), + LazyVerticalStaggeredGrid( + columns = StaggeredGridCells.Adaptive(300.dp), contentPadding = PaddingValues(16.dp), horizontalArrangement = Arrangement.spacedBy(16.dp), - verticalArrangement = Arrangement.spacedBy(24.dp), + verticalItemSpacing = 24.dp, modifier = Modifier .testTag("forYou:feed"), state = state, @@ -197,7 +198,7 @@ internal fun ForYouScreen( onTopicClick = onTopicClick, ) - item(span = { GridItemSpan(maxLineSpan) }, contentType = "bottomSpacing") { + item(span = StaggeredGridItemSpan.FullLine, contentType = "bottomSpacing") { Column { Spacer(modifier = Modifier.height(8.dp)) // Add space for the content to clear the "offline" snackbar. @@ -255,7 +256,7 @@ internal fun ForYouScreen( * Depending on the [onboardingUiState], this might emit no items. * */ -private fun LazyGridScope.onboarding( +private fun LazyStaggeredGridScope.onboarding( onboardingUiState: OnboardingUiState, onTopicCheckedChanged: (String, Boolean) -> Unit, saveFollowedTopics: () -> Unit, @@ -268,7 +269,7 @@ private fun LazyGridScope.onboarding( -> Unit is OnboardingUiState.Shown -> { - item(span = { GridItemSpan(maxLineSpan) }, contentType = "onboarding") { + item(span = StaggeredGridItemSpan.FullLine, contentType = "onboarding") { Column(modifier = interestsItemModifier) { Text( text = stringResource(R.string.onboarding_guidance_title), diff --git a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt b/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt similarity index 98% rename from feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt rename to feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt index 9427cd74c1..2a4b6f4ec3 100644 --- a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt +++ b/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt @@ -111,7 +111,7 @@ class ForYouViewModel @Inject constructor( fun updateTopicSelection(topicId: String, isChecked: Boolean) { viewModelScope.launch { - userDataRepository.toggleFollowedTopicId(topicId, isChecked) + userDataRepository.setTopicIdFollowed(topicId, isChecked) } } diff --git a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/OnboardingUiState.kt b/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/OnboardingUiState.kt similarity index 100% rename from feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/OnboardingUiState.kt rename to feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/OnboardingUiState.kt diff --git a/feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/navigation/ForYouNavigation.kt b/feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/navigation/ForYouNavigation.kt similarity index 100% rename from feature/foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/navigation/ForYouNavigation.kt rename to feature/foryou/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/navigation/ForYouNavigation.kt diff --git a/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenScreenshotTests.kt b/feature/foryou/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenScreenshotTests.kt similarity index 66% rename from feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenScreenshotTests.kt rename to feature/foryou/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenScreenshotTests.kt index 4106196380..1c521d4198 100644 --- a/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenScreenshotTests.kt +++ b/feature/foryou/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenScreenshotTests.kt @@ -17,14 +17,19 @@ package com.google.samples.apps.nowinandroid.feature.foryou import androidx.activity.ComponentActivity +import androidx.compose.runtime.Composable import androidx.compose.ui.test.junit4.createAndroidComposeRule +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaBackground import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme +import com.google.samples.apps.nowinandroid.core.testing.util.DefaultTestDevices +import com.google.samples.apps.nowinandroid.core.testing.util.captureForDevice import com.google.samples.apps.nowinandroid.core.testing.util.captureMultiDevice import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Success import com.google.samples.apps.nowinandroid.core.ui.UserNewsResourcePreviewParameterProvider import com.google.samples.apps.nowinandroid.feature.foryou.OnboardingUiState.Loading import com.google.samples.apps.nowinandroid.feature.foryou.OnboardingUiState.NotShown +import com.google.samples.apps.nowinandroid.feature.foryou.OnboardingUiState.Shown import dagger.hilt.android.testing.HiltTestApplication import org.junit.Before import org.junit.Rule @@ -60,7 +65,7 @@ class ForYouScreenScreenshotTests { } @Test - fun testForYouScreenPopulatedFeed() { + fun forYouScreenPopulatedFeed() { composeTestRule.captureMultiDevice("ForYouScreenPopulatedFeed") { NiaTheme { ForYouScreen( @@ -82,7 +87,7 @@ class ForYouScreenScreenshotTests { } @Test - fun testForYouScreenLoading() { + fun forYouScreenLoading() { composeTestRule.captureMultiDevice("ForYouScreenLoading") { NiaTheme { ForYouScreen( @@ -102,16 +107,54 @@ class ForYouScreenScreenshotTests { } @Test - fun testForYouScreenTopicSelection() { + fun forYouScreenTopicSelection() { composeTestRule.captureMultiDevice("ForYouScreenTopicSelection") { - NiaTheme { + ForYouScreenTopicSelection() + } + } + + @Test + fun forYouScreenTopicSelection_dark() { + composeTestRule.captureForDevice( + deviceName = "phone_dark", + deviceSpec = DefaultTestDevices.PHONE.spec, + screenshotName = "ForYouScreenTopicSelection", + darkMode = true, + ) { + ForYouScreenTopicSelection() + } + } + + @Test + fun forYouScreenPopulatedAndLoading() { + composeTestRule.captureMultiDevice("ForYouScreenPopulatedAndLoading") { + ForYouScreenPopulatedAndLoading() + } + } + + @Test + fun forYouScreenPopulatedAndLoading_dark() { + composeTestRule.captureForDevice( + deviceName = "phone_dark", + deviceSpec = DefaultTestDevices.PHONE.spec, + screenshotName = "ForYouScreenPopulatedAndLoading", + darkMode = true, + ) { + ForYouScreenPopulatedAndLoading() + } + } + + @Composable + private fun ForYouScreenTopicSelection() { + NiaTheme { + NiaBackground { ForYouScreen( isSyncing = false, - onboardingUiState = OnboardingUiState.Shown( + onboardingUiState = Shown( topics = userNewsResources.flatMap { news -> news.followableTopics } .distinctBy { it.topic.id }, ), - feedState = NewsFeedUiState.Success( + feedState = Success( feed = userNewsResources, ), onTopicCheckedChanged = { _, _ -> }, @@ -126,24 +169,26 @@ class ForYouScreenScreenshotTests { } } - @Test - fun testForYouScreenPopulatedAndLoading() { - composeTestRule.captureMultiDevice("ForYouScreenPopulatedAndLoading") { - NiaTheme { - ForYouScreen( - isSyncing = true, - onboardingUiState = OnboardingUiState.Loading, - feedState = NewsFeedUiState.Success( - feed = userNewsResources, - ), - onTopicCheckedChanged = { _, _ -> }, - saveFollowedTopics = {}, - onNewsResourcesCheckedChanged = { _, _ -> }, - onNewsResourceViewed = {}, - onTopicClick = {}, - deepLinkedUserNewsResource = null, - onDeepLinkOpened = {}, - ) + @Composable + private fun ForYouScreenPopulatedAndLoading() { + NiaTheme { + NiaBackground { + NiaTheme { + ForYouScreen( + isSyncing = true, + onboardingUiState = Loading, + feedState = Success( + feed = userNewsResources, + ), + onTopicCheckedChanged = { _, _ -> }, + saveFollowedTopics = {}, + onNewsResourcesCheckedChanged = { _, _ -> }, + onNewsResourceViewed = {}, + onTopicClick = {}, + deepLinkedUserNewsResource = null, + onDeepLinkOpened = {}, + ) + } } } } diff --git a/feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt b/feature/foryou/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt similarity index 100% rename from feature/foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt rename to feature/foryou/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt diff --git a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_foldable.png b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_foldable.png index aa2c122038..deb0cd855f 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_foldable.png and b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_foldable.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_phone.png b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_phone.png index de141fa02d..579bc98a8f 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_phone.png and b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_phone.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_phone_dark.png b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_phone_dark.png new file mode 100644 index 0000000000..f013bb40a5 Binary files /dev/null and b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_phone_dark.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_tablet.png b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_tablet.png index 3fe5194d8d..75d6bc0668 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_tablet.png and b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedAndLoading_tablet.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedFeed_foldable.png b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedFeed_foldable.png index 54ae3be02d..a12c429d9d 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenPopulatedFeed_foldable.png and b/feature/foryou/src/test/screenshots/ForYouScreenPopulatedFeed_foldable.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_foldable.png b/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_foldable.png index 95333c1d11..715889be53 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_foldable.png and b/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_foldable.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_phone.png b/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_phone.png index ab86a2301b..0bbe04955e 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_phone.png and b/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_phone.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_phone_dark.png b/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_phone_dark.png new file mode 100644 index 0000000000..1ba8943ef3 Binary files /dev/null and b/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_phone_dark.png differ diff --git a/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_tablet.png b/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_tablet.png index 292fc22f67..9a51764c57 100644 Binary files a/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_tablet.png and b/feature/foryou/src/test/screenshots/ForYouScreenTopicSelection_tablet.png differ diff --git a/feature/interests/build.gradle.kts b/feature/interests/build.gradle.kts index 5c4b0360a8..20b1ef1aad 100644 --- a/feature/interests/build.gradle.kts +++ b/feature/interests/build.gradle.kts @@ -15,9 +15,9 @@ */ plugins { - id("nowinandroid.android.feature") - id("nowinandroid.android.library.compose") - id("nowinandroid.android.library.jacoco") + alias(libs.plugins.nowinandroid.android.feature) + alias(libs.plugins.nowinandroid.android.library.compose) + alias(libs.plugins.nowinandroid.android.library.jacoco) } android { namespace = "com.google.samples.apps.nowinandroid.feature.interests" diff --git a/feature/interests/src/androidTest/java/com/google/samples/apps/nowinandroid/interests/InterestsScreenTest.kt b/feature/interests/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/interests/InterestsScreenTest.kt similarity index 100% rename from feature/interests/src/androidTest/java/com/google/samples/apps/nowinandroid/interests/InterestsScreenTest.kt rename to feature/interests/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/interests/InterestsScreenTest.kt diff --git a/feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsItem.kt b/feature/interests/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/interests/InterestsItem.kt similarity index 100% rename from feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsItem.kt rename to feature/interests/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/interests/InterestsItem.kt diff --git a/feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsScreen.kt b/feature/interests/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/interests/InterestsScreen.kt similarity index 100% rename from feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsScreen.kt rename to feature/interests/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/interests/InterestsScreen.kt diff --git a/feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsViewModel.kt b/feature/interests/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/interests/InterestsViewModel.kt similarity index 96% rename from feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsViewModel.kt rename to feature/interests/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/interests/InterestsViewModel.kt index c3d5ab6e8a..6d905a6d59 100644 --- a/feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/InterestsViewModel.kt +++ b/feature/interests/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/interests/InterestsViewModel.kt @@ -47,7 +47,7 @@ class InterestsViewModel @Inject constructor( fun followTopic(followedTopicId: String, followed: Boolean) { viewModelScope.launch { - userDataRepository.toggleFollowedTopicId(followedTopicId, followed) + userDataRepository.setTopicIdFollowed(followedTopicId, followed) } } } diff --git a/feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/TabContent.kt b/feature/interests/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/interests/TabContent.kt similarity index 100% rename from feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/TabContent.kt rename to feature/interests/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/interests/TabContent.kt diff --git a/feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/navigation/InterestsNavigation.kt b/feature/interests/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/interests/navigation/InterestsNavigation.kt similarity index 100% rename from feature/interests/src/main/java/com/google/samples/apps/nowinandroid/feature/interests/navigation/InterestsNavigation.kt rename to feature/interests/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/interests/navigation/InterestsNavigation.kt diff --git a/feature/interests/src/test/java/com/google/samples/apps/nowinandroid/interests/InterestsViewModelTest.kt b/feature/interests/src/test/kotlin/com/google/samples/apps/nowinandroid/interests/InterestsViewModelTest.kt similarity index 100% rename from feature/interests/src/test/java/com/google/samples/apps/nowinandroid/interests/InterestsViewModelTest.kt rename to feature/interests/src/test/kotlin/com/google/samples/apps/nowinandroid/interests/InterestsViewModelTest.kt diff --git a/feature/search/build.gradle.kts b/feature/search/build.gradle.kts index cbaa767bcf..d96f290e3f 100644 --- a/feature/search/build.gradle.kts +++ b/feature/search/build.gradle.kts @@ -15,9 +15,9 @@ */ plugins { - id("nowinandroid.android.feature") - id("nowinandroid.android.library.compose") - id("nowinandroid.android.library.jacoco") + alias(libs.plugins.nowinandroid.android.feature) + alias(libs.plugins.nowinandroid.android.library.compose) + alias(libs.plugins.nowinandroid.android.library.jacoco) } android { @@ -25,9 +25,9 @@ android { } dependencies { - implementation(project(":feature:bookmarks")) - implementation(project(":feature:foryou")) - implementation(project(":feature:interests")) + implementation(projects.feature.bookmarks) + implementation(projects.feature.foryou) + implementation(projects.feature.interests) implementation(libs.kotlinx.datetime) } diff --git a/feature/search/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/search/SearchScreenTest.kt b/feature/search/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchScreenTest.kt similarity index 100% rename from feature/search/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/search/SearchScreenTest.kt rename to feature/search/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchScreenTest.kt diff --git a/feature/search/src/main/java/com/google/samples/apps/nowinandroid/feature/search/RecentSearchQueriesUiState.kt b/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/RecentSearchQueriesUiState.kt similarity index 100% rename from feature/search/src/main/java/com/google/samples/apps/nowinandroid/feature/search/RecentSearchQueriesUiState.kt rename to feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/RecentSearchQueriesUiState.kt diff --git a/feature/search/src/main/java/com/google/samples/apps/nowinandroid/feature/search/SearchResultUiState.kt b/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchResultUiState.kt similarity index 100% rename from feature/search/src/main/java/com/google/samples/apps/nowinandroid/feature/search/SearchResultUiState.kt rename to feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchResultUiState.kt diff --git a/feature/search/src/main/java/com/google/samples/apps/nowinandroid/feature/search/SearchScreen.kt b/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchScreen.kt similarity index 96% rename from feature/search/src/main/java/com/google/samples/apps/nowinandroid/feature/search/SearchScreen.kt rename to feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchScreen.kt index 944d17630c..65b65f61d8 100644 --- a/feature/search/src/main/java/com/google/samples/apps/nowinandroid/feature/search/SearchScreen.kt +++ b/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchScreen.kt @@ -35,11 +35,11 @@ import androidx.compose.foundation.layout.windowInsetsBottomHeight import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.layout.windowInsetsTopHeight import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.grid.GridCells.Adaptive -import androidx.compose.foundation.lazy.grid.GridItemSpan -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.foundation.lazy.grid.rememberLazyGridState import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid +import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells +import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan +import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.ClickableText import androidx.compose.foundation.text.KeyboardActions @@ -297,16 +297,16 @@ private fun SearchResultBody( onTopicClick: (String) -> Unit, searchQuery: String = "", ) { - val state = rememberLazyGridState() + val state = rememberLazyStaggeredGridState() Box( modifier = Modifier .fillMaxSize(), ) { - LazyVerticalGrid( - columns = Adaptive(300.dp), + LazyVerticalStaggeredGrid( + columns = StaggeredGridCells.Adaptive(300.dp), contentPadding = PaddingValues(16.dp), horizontalArrangement = Arrangement.spacedBy(16.dp), - verticalArrangement = Arrangement.spacedBy(24.dp), + verticalItemSpacing = 24.dp, modifier = Modifier .fillMaxSize() .testTag("search:newsResources"), @@ -314,9 +314,7 @@ private fun SearchResultBody( ) { if (topics.isNotEmpty()) { item( - span = { - GridItemSpan(maxLineSpan) - }, + span = StaggeredGridItemSpan.FullLine, ) { Text( text = buildAnnotatedString { @@ -331,9 +329,7 @@ private fun SearchResultBody( val topicId = followableTopic.topic.id item( key = "topic-$topicId", // Append a prefix to distinguish a key for news resources - span = { - GridItemSpan(maxLineSpan) - }, + span = StaggeredGridItemSpan.FullLine, ) { InterestsItem( name = followableTopic.topic.name, @@ -353,9 +349,7 @@ private fun SearchResultBody( if (newsResources.isNotEmpty()) { item( - span = { - GridItemSpan(maxLineSpan) - }, + span = StaggeredGridItemSpan.FullLine, ) { Text( text = buildAnnotatedString { diff --git a/feature/search/src/main/java/com/google/samples/apps/nowinandroid/feature/search/SearchUiStatePreviewParameterProvider.kt b/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchUiStatePreviewParameterProvider.kt similarity index 100% rename from feature/search/src/main/java/com/google/samples/apps/nowinandroid/feature/search/SearchUiStatePreviewParameterProvider.kt rename to feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchUiStatePreviewParameterProvider.kt diff --git a/feature/search/src/main/java/com/google/samples/apps/nowinandroid/feature/search/SearchViewModel.kt b/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModel.kt similarity index 100% rename from feature/search/src/main/java/com/google/samples/apps/nowinandroid/feature/search/SearchViewModel.kt rename to feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModel.kt diff --git a/feature/search/src/main/java/com/google/samples/apps/nowinandroid/feature/search/navigation/SearchNavigation.kt b/feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/navigation/SearchNavigation.kt similarity index 100% rename from feature/search/src/main/java/com/google/samples/apps/nowinandroid/feature/search/navigation/SearchNavigation.kt rename to feature/search/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/search/navigation/SearchNavigation.kt diff --git a/feature/search/src/test/java/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt b/feature/search/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt similarity index 100% rename from feature/search/src/test/java/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt rename to feature/search/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt diff --git a/feature/settings/build.gradle.kts b/feature/settings/build.gradle.kts index ef367d612a..4f5d649b7d 100644 --- a/feature/settings/build.gradle.kts +++ b/feature/settings/build.gradle.kts @@ -15,9 +15,9 @@ */ plugins { - id("nowinandroid.android.feature") - id("nowinandroid.android.library.compose") - id("nowinandroid.android.library.jacoco") + alias(libs.plugins.nowinandroid.android.feature) + alias(libs.plugins.nowinandroid.android.library.compose) + alias(libs.plugins.nowinandroid.android.library.jacoco) } android { diff --git a/feature/settings/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/settings/SettingsDialogTest.kt b/feature/settings/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsDialogTest.kt similarity index 100% rename from feature/settings/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/settings/SettingsDialogTest.kt rename to feature/settings/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsDialogTest.kt diff --git a/feature/settings/src/main/java/com/google/samples/apps/nowinandroid/feature/settings/SettingsDialog.kt b/feature/settings/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsDialog.kt similarity index 100% rename from feature/settings/src/main/java/com/google/samples/apps/nowinandroid/feature/settings/SettingsDialog.kt rename to feature/settings/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsDialog.kt diff --git a/feature/settings/src/main/java/com/google/samples/apps/nowinandroid/feature/settings/SettingsViewModel.kt b/feature/settings/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsViewModel.kt similarity index 98% rename from feature/settings/src/main/java/com/google/samples/apps/nowinandroid/feature/settings/SettingsViewModel.kt rename to feature/settings/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsViewModel.kt index 33bf58a2cd..a49c0d5128 100644 --- a/feature/settings/src/main/java/com/google/samples/apps/nowinandroid/feature/settings/SettingsViewModel.kt +++ b/feature/settings/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsViewModel.kt @@ -87,6 +87,6 @@ data class UserEditableSettings( ) sealed interface SettingsUiState { - object Loading : SettingsUiState + data object Loading : SettingsUiState data class Success(val settings: UserEditableSettings) : SettingsUiState } diff --git a/feature/settings/src/test/java/com/google/samples/apps/nowinandroid/feature/settings/SettingsViewModelTest.kt b/feature/settings/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsViewModelTest.kt similarity index 100% rename from feature/settings/src/test/java/com/google/samples/apps/nowinandroid/feature/settings/SettingsViewModelTest.kt rename to feature/settings/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/settings/SettingsViewModelTest.kt diff --git a/feature/topic/build.gradle.kts b/feature/topic/build.gradle.kts index ecb0630ce6..cc0ecc8683 100644 --- a/feature/topic/build.gradle.kts +++ b/feature/topic/build.gradle.kts @@ -15,9 +15,9 @@ */ plugins { - id("nowinandroid.android.feature") - id("nowinandroid.android.library.compose") - id("nowinandroid.android.library.jacoco") + alias(libs.plugins.nowinandroid.android.feature) + alias(libs.plugins.nowinandroid.android.library.compose) + alias(libs.plugins.nowinandroid.android.library.jacoco) } android { diff --git a/feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt b/feature/topic/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt similarity index 100% rename from feature/topic/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt rename to feature/topic/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicScreenTest.kt diff --git a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt b/feature/topic/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt similarity index 100% rename from feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt rename to feature/topic/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicScreen.kt diff --git a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt b/feature/topic/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt similarity index 96% rename from feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt rename to feature/topic/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt index 7f8c6067ee..6adfe0a671 100644 --- a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt +++ b/feature/topic/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModel.kt @@ -75,7 +75,7 @@ class TopicViewModel @Inject constructor( fun followTopicToggle(followed: Boolean) { viewModelScope.launch { - userDataRepository.toggleFollowedTopicId(topicArgs.topicId, followed) + userDataRepository.setTopicIdFollowed(topicArgs.topicId, followed) } } @@ -177,12 +177,12 @@ private fun newsUiState( sealed interface TopicUiState { data class Success(val followableTopic: FollowableTopic) : TopicUiState - object Error : TopicUiState - object Loading : TopicUiState + data object Error : TopicUiState + data object Loading : TopicUiState } sealed interface NewsUiState { data class Success(val news: List) : NewsUiState - object Error : NewsUiState - object Loading : NewsUiState + data object Error : NewsUiState + data object Loading : NewsUiState } diff --git a/feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/navigation/TopicNavigation.kt b/feature/topic/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/topic/navigation/TopicNavigation.kt similarity index 100% rename from feature/topic/src/main/java/com/google/samples/apps/nowinandroid/feature/topic/navigation/TopicNavigation.kt rename to feature/topic/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/topic/navigation/TopicNavigation.kt diff --git a/feature/topic/src/test/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt b/feature/topic/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt similarity index 100% rename from feature/topic/src/test/java/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt rename to feature/topic/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt diff --git a/gradle.properties b/gradle.properties index b57dc01ed0..c4159cfea4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -31,9 +31,6 @@ android.useAndroidX=true # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official -# Non-transitive R classes is recommended and is faster/smaller -android.nonTransitiveRClass=true - # Disable build features that are enabled by default, # https://developer.android.com/build/releases/gradle-plugin#default-changes android.defaults.buildfeatures.resvalues=false diff --git a/gradle/init.gradle.kts b/gradle/init.gradle.kts index 57f91da088..72f3eebe02 100644 --- a/gradle/init.gradle.kts +++ b/gradle/init.gradle.kts @@ -17,7 +17,7 @@ val ktlintVersion = "0.48.1" initscript { - val spotlessVersion = "6.13.0" + val spotlessVersion = "6.22.0" repositories { mavenCentral() diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 216a899a50..aaa8ee1c37 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,59 +1,61 @@ [versions] -accompanist = "0.28.0" +accompanist = "0.32.0" androidDesugarJdkLibs = "2.0.3" -androidGradlePlugin = "8.1.0" -androidxActivity = "1.8.0-alpha06" -androidxAppCompat = "1.5.1" -androidxBrowser = "1.4.0" -androidxComposeBom = "2023.06.01" -androidxComposeCompiler = "1.5.0" +# AGP and tools should be updated together +androidGradlePlugin = "8.1.2" +androidTools = "31.1.2" +androidxActivity = "1.8.0" +androidxAppCompat = "1.6.1" +androidxBrowser = "1.6.0" +androidxComposeBom = "2023.10.01" +androidxComposeCompiler = "1.5.3" androidxComposeRuntimeTracing = "1.0.0-alpha03" -androidxCore = "1.9.0" -androidxCoreSplashscreen = "1.0.0" +androidxCore = "1.12.0" +androidxCoreSplashscreen = "1.0.1" androidxDataStore = "1.0.0" -androidxEspresso = "3.5.0" +androidxEspresso = "3.5.1" androidxHiltNavigationCompose = "1.0.0" -androidxLifecycle = "2.6.1" -androidxMacroBenchmark = "1.2.0-alpha16" -androidxMetrics = "1.0.0-alpha03" -androidxNavigation = "2.5.3" +androidxLifecycle = "2.6.2" +androidxMacroBenchmark = "1.2.0" +androidxMetrics = "1.0.0-alpha04" +androidxNavigation = "2.7.4" androidxProfileinstaller = "1.3.1" androidxStartup = "1.1.1" androidxTestCore = "1.5.0" -androidxTestExt = "1.1.4" +androidxTestExt = "1.1.5" androidxTestRules = "1.5.0" -androidxTestRunner = "1.5.1" +androidxTestRunner = "1.5.2" androidxTracing = "1.1.0" androidxUiAutomator = "2.2.0" -androidxWindowManager = "1.0.0" -androidxWork = "2.9.0-alpha01" -coil = "2.2.2" -firebaseBom = "31.2.0" -firebaseCrashlyticsPlugin = "2.9.2" +androidxWindowManager = "1.1.0" +androidxWork = "2.9.0-rc01" +coil = "2.4.0" +firebaseBom = "32.4.0" +firebaseCrashlyticsPlugin = "2.9.9" firebasePerfPlugin = "1.4.2" -gmsPlugin = "4.3.14" +gmsPlugin = "4.4.0" googleOss = "17.0.1" googleOssPlugin = "0.10.6" -hilt = "2.48" +hilt = "2.48.1" hiltExt = "1.1.0-alpha01" jacoco = "0.8.7" junit4 = "4.13.2" -kotlin = "1.9.0" -kotlinxCoroutines = "1.6.4" -kotlinxDatetime = "0.4.0" -kotlinxSerializationJson = "1.5.1" -ksp = "1.9.0-1.0.13" -lint = "31.0.2" -okhttp = "4.10.0" -protobuf = "3.24.0" +kotlin = "1.9.10" +kotlinxCoroutines = "1.7.3" +kotlinxDatetime = "0.4.1" +kotlinxSerializationJson = "1.6.0" +ksp = "1.9.10-1.0.13" +lint = "31.1.2" +okhttp = "4.12.0" +protobuf = "3.24.4" protobufPlugin = "0.9.4" retrofit = "2.9.0" retrofitKotlinxSerializationJson = "1.0.0" robolectric = "4.10.3" -roborazzi = "1.5.0-alpha-2" -room = "2.5.2" +roborazzi = "1.6.0" +room = "2.6.0" secrets = "2.0.1" -turbine = "0.12.1" +turbine = "1.0.0" [libraries] accompanist-permissions = { group = "com.google.accompanist", name = "accompanist-permissions", version.ref = "accompanist" } @@ -122,6 +124,8 @@ kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-cor kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinxDatetime" } kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" } lint-api = { group = "com.android.tools.lint", name = "lint-api", version.ref = "lint" } +lint-checks = { group = "com.android.tools.lint", name = "lint-checks", version.ref = "lint" } +lint-tests = { group = "com.android.tools.lint", name = "lint-tests", version.ref = "lint" } okhttp-logging = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" } protobuf-kotlin-lite = { group = "com.google.protobuf", name = "protobuf-kotlin-lite", version.ref = "protobuf" } protobuf-protoc = { group = "com.google.protobuf", name = "protoc", version.ref = "protobuf" } @@ -137,6 +141,7 @@ turbine = { group = "app.cash.turbine", name = "turbine", version.ref = "turbine # Dependencies of the included build-logic android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" } +android-tools-common = { group = "com.android.tools", name = "common", version.ref = "androidTools" } firebase-crashlytics-gradlePlugin = { group = "com.google.firebase", name = "firebase-crashlytics-gradle", version.ref = "firebaseCrashlyticsPlugin" } firebase-performance-gradlePlugin = { group = "com.google.firebase", name = "perf-plugin", version.ref = "firebasePerfPlugin" } kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" } @@ -157,3 +162,19 @@ ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } protobuf = { id = "com.google.protobuf", version.ref = "protobufPlugin" } roborazzi = { id = "io.github.takahirom.roborazzi", version.ref = "roborazzi" } secrets = { id = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin", version.ref = "secrets" } + +# Plugins defined by this project +nowinandroid-android-application = { id = "nowinandroid.android.application", version = "unspecified" } +nowinandroid-android-application-compose = { id = "nowinandroid.android.application.compose", version = "unspecified" } +nowinandroid-android-application-firebase = { id = "nowinandroid.android.application.firebase", version = "unspecified" } +nowinandroid-android-application-flavors = { id = "nowinandroid.android.application.flavors", version = "unspecified" } +nowinandroid-android-application-jacoco = { id = "nowinandroid.android.application.jacoco", version = "unspecified" } +nowinandroid-android-feature = { id = "nowinandroid.android.feature", version = "unspecified" } +nowinandroid-android-hilt = { id = "nowinandroid.android.hilt", version = "unspecified" } +nowinandroid-android-library = { id = "nowinandroid.android.library", version = "unspecified" } +nowinandroid-android-library-compose = { id = "nowinandroid.android.library.compose", version = "unspecified" } +nowinandroid-android-library-jacoco = { id = "nowinandroid.android.library.jacoco", version = "unspecified" } +nowinandroid-android-lint = { id = "nowinandroid.android.lint", version = "unspecified" } +nowinandroid-android-room = { id = "nowinandroid.android.room", version = "unspecified" } +nowinandroid-android-test = { id = "nowinandroid.android.test", version = "unspecified" } +nowinandroid-jvm-library = { id = "nowinandroid.jvm.library", version = "unspecified" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 033e24c4cd..7f93135c49 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 62f495dfed..3fa8f862f7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index fcb6fca147..1aa94a4269 100755 --- a/gradlew +++ b/gradlew @@ -83,7 +83,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -201,11 +202,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/lint/build.gradle.kts b/lint/build.gradle.kts index 35b6ec1e88..acb540c3b2 100644 --- a/lint/build.gradle.kts +++ b/lint/build.gradle.kts @@ -19,7 +19,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { `java-library` kotlin("jvm") - id("nowinandroid.android.lint") + alias(libs.plugins.nowinandroid.android.lint) } java { @@ -38,4 +38,7 @@ tasks.withType().configureEach { dependencies { compileOnly(libs.kotlin.stdlib) compileOnly(libs.lint.api) + testImplementation(libs.lint.checks) + testImplementation(libs.lint.tests) + testImplementation(kotlin("test")) } diff --git a/lint/src/main/java/com/google/samples/apps/nowinandroid/lint/designsystem/DesignSystemIssueRegistry.kt b/lint/src/main/kotlin/com/google/samples/apps/nowinandroid/lint/NiaIssueRegistry.kt similarity index 76% rename from lint/src/main/java/com/google/samples/apps/nowinandroid/lint/designsystem/DesignSystemIssueRegistry.kt rename to lint/src/main/kotlin/com/google/samples/apps/nowinandroid/lint/NiaIssueRegistry.kt index bb7e971e36..b806312fd1 100644 --- a/lint/src/main/java/com/google/samples/apps/nowinandroid/lint/designsystem/DesignSystemIssueRegistry.kt +++ b/lint/src/main/kotlin/com/google/samples/apps/nowinandroid/lint/NiaIssueRegistry.kt @@ -14,18 +14,20 @@ * limitations under the License. */ -package com.google.samples.apps.nowinandroid.lint.designsystem +package com.google.samples.apps.nowinandroid.lint import com.android.tools.lint.client.api.IssueRegistry import com.android.tools.lint.client.api.Vendor import com.android.tools.lint.detector.api.CURRENT_API +import com.google.samples.apps.nowinandroid.lint.designsystem.DesignSystemDetector -/** - * An issue registry that checks for incorrect usages of Compose Material APIs over equivalents in - * the Now in Android design system module. - */ -class DesignSystemIssueRegistry : IssueRegistry() { - override val issues = listOf(DesignSystemDetector.ISSUE) +class NiaIssueRegistry : IssueRegistry() { + + override val issues = listOf( + DesignSystemDetector.ISSUE, + TestMethodNameDetector.FORMAT, + TestMethodNameDetector.PREFIX, + ) override val api: Int = CURRENT_API diff --git a/lint/src/main/kotlin/com/google/samples/apps/nowinandroid/lint/TestMethodNameDetector.kt b/lint/src/main/kotlin/com/google/samples/apps/nowinandroid/lint/TestMethodNameDetector.kt new file mode 100644 index 0000000000..532994d992 --- /dev/null +++ b/lint/src/main/kotlin/com/google/samples/apps/nowinandroid/lint/TestMethodNameDetector.kt @@ -0,0 +1,126 @@ +/* + * Copyright 2023 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.lint + +import com.android.tools.lint.detector.api.AnnotationInfo +import com.android.tools.lint.detector.api.AnnotationUsageInfo +import com.android.tools.lint.detector.api.Category.Companion.TESTING +import com.android.tools.lint.detector.api.Detector +import com.android.tools.lint.detector.api.Implementation +import com.android.tools.lint.detector.api.Issue +import com.android.tools.lint.detector.api.JavaContext +import com.android.tools.lint.detector.api.LintFix +import com.android.tools.lint.detector.api.Scope.JAVA_FILE +import com.android.tools.lint.detector.api.Scope.TEST_SOURCES +import com.android.tools.lint.detector.api.Severity.WARNING +import com.android.tools.lint.detector.api.SourceCodeScanner +import com.android.tools.lint.detector.api.TextFormat.RAW +import com.intellij.psi.PsiMethod +import org.jetbrains.uast.UElement +import java.util.EnumSet +import kotlin.io.path.Path + +/** + * A detector that checks for common patterns in naming the test methods: + * - [detectPrefix] removes unnecessary "test" prefix in all unit test. + * - [detectFormat] Checks the `given_when_then` format of Android instrumented tests (backticks are not supported). + */ +class TestMethodNameDetector : Detector(), SourceCodeScanner { + + override fun applicableAnnotations() = listOf("org.junit.Test") + + override fun visitAnnotationUsage( + context: JavaContext, + element: UElement, + annotationInfo: AnnotationInfo, + usageInfo: AnnotationUsageInfo, + ) { + val method = usageInfo.referenced as? PsiMethod ?: return + + method.detectPrefix(context, usageInfo) + method.detectFormat(context, usageInfo) + } + + private fun JavaContext.isAndroidTest() = Path("androidTest") in file.toPath() + + private fun PsiMethod.detectPrefix( + context: JavaContext, + usageInfo: AnnotationUsageInfo, + ) { + if (!name.startsWith("test")) return + context.report( + issue = PREFIX, + scope = usageInfo.usage, + location = context.getNameLocation(this), + message = PREFIX.getBriefDescription(RAW), + quickfixData = LintFix.create() + .name("Remove prefix") + .replace().pattern("""test[\s_]*""") + .with("") + .autoFix() + .build(), + ) + } + + private fun PsiMethod.detectFormat( + context: JavaContext, + usageInfo: AnnotationUsageInfo, + ) { + if (!context.isAndroidTest()) return + if ("""[^\W_]+(_[^\W_]+){1,2}""".toRegex().matches(name)) return + context.report( + issue = FORMAT, + scope = usageInfo.usage, + location = context.getNameLocation(this), + message = FORMAT.getBriefDescription(RAW), + ) + } + + companion object { + + private fun issue( + id: String, + briefDescription: String, + explanation: String, + ): Issue = Issue.create( + id = id, + briefDescription = briefDescription, + explanation = explanation, + category = TESTING, + priority = 5, + severity = WARNING, + implementation = Implementation( + TestMethodNameDetector::class.java, + EnumSet.of(JAVA_FILE, TEST_SOURCES), + ), + ) + + @JvmField + val PREFIX: Issue = issue( + id = "TestMethodPrefix", + briefDescription = "Test method starts with `test`", + explanation = "Test method should not start with `test`.", + ) + + @JvmField + val FORMAT: Issue = issue( + id = "TestMethodFormat", + briefDescription = "Test method does not follow the `given_when_then` or `when_then` format", + explanation = "Test method should follow the `given_when_then` or `when_then` format.", + ) + } +} diff --git a/lint/src/main/java/com/google/samples/apps/nowinandroid/lint/designsystem/DesignSystemDetector.kt b/lint/src/main/kotlin/com/google/samples/apps/nowinandroid/lint/designsystem/DesignSystemDetector.kt similarity index 100% rename from lint/src/main/java/com/google/samples/apps/nowinandroid/lint/designsystem/DesignSystemDetector.kt rename to lint/src/main/kotlin/com/google/samples/apps/nowinandroid/lint/designsystem/DesignSystemDetector.kt diff --git a/lint/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry b/lint/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry index 4b8002da2a..e673c27fff 100644 --- a/lint/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry +++ b/lint/src/main/resources/META-INF/services/com.android.tools.lint.client.api.IssueRegistry @@ -14,4 +14,4 @@ # limitations under the License. # -com.google.samples.apps.nowinandroid.lint.designsystem.DesignSystemIssueRegistry +com.google.samples.apps.nowinandroid.lint.NiaIssueRegistry diff --git a/lint/src/test/kotlin/com/google/samples/apps/nowinandroid/lint/TestMethodNameDetectorTest.kt b/lint/src/test/kotlin/com/google/samples/apps/nowinandroid/lint/TestMethodNameDetectorTest.kt new file mode 100644 index 0000000000..8da173285f --- /dev/null +++ b/lint/src/test/kotlin/com/google/samples/apps/nowinandroid/lint/TestMethodNameDetectorTest.kt @@ -0,0 +1,123 @@ +/* + * Copyright 2023 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.lint + +import com.android.tools.lint.checks.infrastructure.TestFile +import com.android.tools.lint.checks.infrastructure.TestFiles.kotlin +import com.android.tools.lint.checks.infrastructure.TestLintTask.lint +import com.google.samples.apps.nowinandroid.lint.TestMethodNameDetector.Companion.FORMAT +import com.google.samples.apps.nowinandroid.lint.TestMethodNameDetector.Companion.PREFIX +import org.junit.Test + +class TestMethodNameDetectorTest { + + @Test + fun `detect prefix`() { + lint().issues(PREFIX) + .files( + JUNIT_TEST_STUB, + kotlin( + """ + import org.junit.Test + class Test { + @Test + fun foo() = Unit + @Test + fun test_foo() = Unit + @Test + fun `test foo`() = Unit + } + """, + ).indented(), + ) + .run() + .expect( + """ + src/Test.kt:6: Warning: Test method starts with test [TestMethodPrefix] + fun test_foo() = Unit + ~~~~~~~~ + src/Test.kt:8: Warning: Test method starts with test [TestMethodPrefix] + fun `test foo`() = Unit + ~~~~~~~~~~ + 0 errors, 2 warnings + """.trimIndent(), + ) + .expectFixDiffs( + """ + Autofix for src/Test.kt line 6: Remove prefix: + @@ -6 +6 + - fun test_foo() = Unit + + fun foo() = Unit + Autofix for src/Test.kt line 8: Remove prefix: + @@ -8 +8 + - fun `test foo`() = Unit + + fun `foo`() = Unit + """.trimIndent(), + ) + } + + @Test + fun `detect format`() { + lint().issues(FORMAT) + .files( + JUNIT_TEST_STUB, + kotlin( + "src/androidTest/com/example/Test.kt", + """ + import org.junit.Test + class Test { + @Test + fun when_then() = Unit + @Test + fun given_when_then() = Unit + + @Test + fun foo() = Unit + @Test + fun foo_bar_baz_qux() = Unit + @Test + fun `foo bar baz`() = Unit + } + """, + ).indented(), + ) + .run() + .expect( + """ + src/androidTest/com/example/Test.kt:9: Warning: Test method does not follow the given_when_then or when_then format [TestMethodFormat] + fun foo() = Unit + ~~~ + src/androidTest/com/example/Test.kt:11: Warning: Test method does not follow the given_when_then or when_then format [TestMethodFormat] + fun foo_bar_baz_qux() = Unit + ~~~~~~~~~~~~~~~ + src/androidTest/com/example/Test.kt:13: Warning: Test method does not follow the given_when_then or when_then format [TestMethodFormat] + fun `foo bar baz`() = Unit + ~~~~~~~~~~~~~ + 0 errors, 3 warnings + """.trimIndent(), + ) + } + + private companion object { + private val JUNIT_TEST_STUB: TestFile = kotlin( + """ + package org.junit + annotation class Test + """, + ).indented() + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 3bb41a224a..fa043c955a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -31,6 +31,8 @@ dependencyResolutionManagement { } } rootProject.name = "nowinandroid" + +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") include(":app") include(":app-nia-catalog") include(":benchmarks") diff --git a/sync/sync-test/build.gradle.kts b/sync/sync-test/build.gradle.kts index 99909af6b5..02e573ae50 100644 --- a/sync/sync-test/build.gradle.kts +++ b/sync/sync-test/build.gradle.kts @@ -14,8 +14,8 @@ * limitations under the License. */ plugins { - id("nowinandroid.android.library") - id("nowinandroid.android.hilt") + alias(libs.plugins.nowinandroid.android.library) + alias(libs.plugins.nowinandroid.android.hilt) } android { @@ -23,7 +23,7 @@ android { } dependencies { - api(project(":sync:work")) - implementation(project(":core:data")) - implementation(project(":core:testing")) + api(projects.sync.work) + implementation(projects.core.data) + implementation(projects.core.testing) } diff --git a/sync/sync-test/src/main/java/com/google/samples/apps/nowinandroid/core/sync/test/NeverSyncingSyncManager.kt b/sync/sync-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/sync/test/NeverSyncingSyncManager.kt similarity index 100% rename from sync/sync-test/src/main/java/com/google/samples/apps/nowinandroid/core/sync/test/NeverSyncingSyncManager.kt rename to sync/sync-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/sync/test/NeverSyncingSyncManager.kt diff --git a/sync/sync-test/src/main/java/com/google/samples/apps/nowinandroid/core/sync/test/TestSyncModule.kt b/sync/sync-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/sync/test/TestSyncModule.kt similarity index 100% rename from sync/sync-test/src/main/java/com/google/samples/apps/nowinandroid/core/sync/test/TestSyncModule.kt rename to sync/sync-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/sync/test/TestSyncModule.kt diff --git a/sync/work/build.gradle.kts b/sync/work/build.gradle.kts index a4bfff2132..867aef17c1 100644 --- a/sync/work/build.gradle.kts +++ b/sync/work/build.gradle.kts @@ -14,9 +14,9 @@ * limitations under the License. */ plugins { - id("nowinandroid.android.library") - id("nowinandroid.android.library.jacoco") - id("nowinandroid.android.hilt") + alias(libs.plugins.nowinandroid.android.library) + alias(libs.plugins.nowinandroid.android.library.jacoco) + alias(libs.plugins.nowinandroid.android.hilt) } android { @@ -27,22 +27,23 @@ android { } dependencies { - implementation(project(":core:analytics")) - implementation(project(":core:common")) - implementation(project(":core:data")) - implementation(project(":core:datastore")) - implementation(project(":core:model")) + implementation(projects.core.analytics) + implementation(projects.core.common) + implementation(projects.core.data) + implementation(projects.core.datastore) + implementation(projects.core.model) implementation(libs.androidx.lifecycle.livedata.ktx) implementation(libs.androidx.tracing.ktx) implementation(libs.androidx.work.ktx) - implementation(libs.firebase.cloud.messaging) implementation(libs.hilt.ext.work) implementation(libs.kotlinx.coroutines.android) + prodImplementation(libs.firebase.cloud.messaging) + ksp(libs.hilt.ext.compiler) - testImplementation(project(":core:testing")) + testImplementation(projects.core.testing) - androidTestImplementation(project(":core:testing")) + androidTestImplementation(projects.core.testing) androidTestImplementation(libs.androidx.work.testing) } diff --git a/sync/work/src/androidTest/java/com/google/samples/apps/nowinandroid/sync/workers/SyncWorkerTest.kt b/sync/work/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/sync/workers/SyncWorkerTest.kt similarity index 100% rename from sync/work/src/androidTest/java/com/google/samples/apps/nowinandroid/sync/workers/SyncWorkerTest.kt rename to sync/work/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/sync/workers/SyncWorkerTest.kt diff --git a/sync/work/src/demo/java/com/google/samples/apps/nowinandroid/sync/di/SyncModule.kt b/sync/work/src/demo/kotlin/com/google/samples/apps/nowinandroid/sync/di/SyncModule.kt similarity index 100% rename from sync/work/src/demo/java/com/google/samples/apps/nowinandroid/sync/di/SyncModule.kt rename to sync/work/src/demo/kotlin/com/google/samples/apps/nowinandroid/sync/di/SyncModule.kt diff --git a/sync/work/src/main/java/com/google/samples/apps/nowinandroid/sync/initializers/SyncInitializer.kt b/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/initializers/SyncInitializer.kt similarity index 100% rename from sync/work/src/main/java/com/google/samples/apps/nowinandroid/sync/initializers/SyncInitializer.kt rename to sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/initializers/SyncInitializer.kt diff --git a/sync/work/src/main/java/com/google/samples/apps/nowinandroid/sync/initializers/SyncWorkHelpers.kt b/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/initializers/SyncWorkHelpers.kt similarity index 100% rename from sync/work/src/main/java/com/google/samples/apps/nowinandroid/sync/initializers/SyncWorkHelpers.kt rename to sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/initializers/SyncWorkHelpers.kt diff --git a/sync/work/src/main/java/com/google/samples/apps/nowinandroid/sync/status/StubSyncSubscriber.kt b/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/status/StubSyncSubscriber.kt similarity index 100% rename from sync/work/src/main/java/com/google/samples/apps/nowinandroid/sync/status/StubSyncSubscriber.kt rename to sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/status/StubSyncSubscriber.kt diff --git a/sync/work/src/main/java/com/google/samples/apps/nowinandroid/sync/status/SyncSubscriber.kt b/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/status/SyncSubscriber.kt similarity index 100% rename from sync/work/src/main/java/com/google/samples/apps/nowinandroid/sync/status/SyncSubscriber.kt rename to sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/status/SyncSubscriber.kt diff --git a/sync/work/src/main/java/com/google/samples/apps/nowinandroid/sync/status/WorkManagerSyncManager.kt b/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/status/WorkManagerSyncManager.kt similarity index 100% rename from sync/work/src/main/java/com/google/samples/apps/nowinandroid/sync/status/WorkManagerSyncManager.kt rename to sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/status/WorkManagerSyncManager.kt diff --git a/sync/work/src/main/java/com/google/samples/apps/nowinandroid/sync/workers/AnalyticsExtensions.kt b/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/workers/AnalyticsExtensions.kt similarity index 100% rename from sync/work/src/main/java/com/google/samples/apps/nowinandroid/sync/workers/AnalyticsExtensions.kt rename to sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/workers/AnalyticsExtensions.kt diff --git a/sync/work/src/main/java/com/google/samples/apps/nowinandroid/sync/workers/DelegatingWorker.kt b/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/workers/DelegatingWorker.kt similarity index 100% rename from sync/work/src/main/java/com/google/samples/apps/nowinandroid/sync/workers/DelegatingWorker.kt rename to sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/workers/DelegatingWorker.kt diff --git a/sync/work/src/main/java/com/google/samples/apps/nowinandroid/sync/workers/SyncWorker.kt b/sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/workers/SyncWorker.kt similarity index 100% rename from sync/work/src/main/java/com/google/samples/apps/nowinandroid/sync/workers/SyncWorker.kt rename to sync/work/src/main/kotlin/com/google/samples/apps/nowinandroid/sync/workers/SyncWorker.kt diff --git a/sync/work/src/main/AndroidManifest.xml b/sync/work/src/prod/AndroidManifest.xml similarity index 100% rename from sync/work/src/main/AndroidManifest.xml rename to sync/work/src/prod/AndroidManifest.xml diff --git a/sync/work/src/prod/java/com/google/samples/apps/nowinandroid/sync/di/SyncModule.kt b/sync/work/src/prod/kotlin/com/google/samples/apps/nowinandroid/sync/di/SyncModule.kt similarity index 100% rename from sync/work/src/prod/java/com/google/samples/apps/nowinandroid/sync/di/SyncModule.kt rename to sync/work/src/prod/kotlin/com/google/samples/apps/nowinandroid/sync/di/SyncModule.kt diff --git a/sync/work/src/main/java/com/google/samples/apps/nowinandroid/sync/services/SyncNotificationsService.kt b/sync/work/src/prod/kotlin/com/google/samples/apps/nowinandroid/sync/services/SyncNotificationsService.kt similarity index 100% rename from sync/work/src/main/java/com/google/samples/apps/nowinandroid/sync/services/SyncNotificationsService.kt rename to sync/work/src/prod/kotlin/com/google/samples/apps/nowinandroid/sync/services/SyncNotificationsService.kt diff --git a/sync/work/src/prod/java/com/google/samples/apps/nowinandroid/sync/status/FirebaseSyncSubscriber.kt b/sync/work/src/prod/kotlin/com/google/samples/apps/nowinandroid/sync/status/FirebaseSyncSubscriber.kt similarity index 100% rename from sync/work/src/prod/java/com/google/samples/apps/nowinandroid/sync/status/FirebaseSyncSubscriber.kt rename to sync/work/src/prod/kotlin/com/google/samples/apps/nowinandroid/sync/status/FirebaseSyncSubscriber.kt diff --git a/ui-test-hilt-manifest/build.gradle.kts b/ui-test-hilt-manifest/build.gradle.kts index b55036591a..f41482814e 100644 --- a/ui-test-hilt-manifest/build.gradle.kts +++ b/ui-test-hilt-manifest/build.gradle.kts @@ -14,8 +14,8 @@ * limitations under the License. */ plugins { - id("nowinandroid.android.library") - id("nowinandroid.android.hilt") + alias(libs.plugins.nowinandroid.android.library) + alias(libs.plugins.nowinandroid.android.hilt) } android { diff --git a/ui-test-hilt-manifest/src/main/java/com/google/samples/apps/nowinandroid/uitesthiltmanifest/HiltComponentActivity.kt b/ui-test-hilt-manifest/src/main/kotlin/com/google/samples/apps/nowinandroid/uitesthiltmanifest/HiltComponentActivity.kt similarity index 100% rename from ui-test-hilt-manifest/src/main/java/com/google/samples/apps/nowinandroid/uitesthiltmanifest/HiltComponentActivity.kt rename to ui-test-hilt-manifest/src/main/kotlin/com/google/samples/apps/nowinandroid/uitesthiltmanifest/HiltComponentActivity.kt