From 25a9bdad3f0a75212666f290ca2e27a5ef3d948e Mon Sep 17 00:00:00 2001 From: Robert Date: Sat, 27 Aug 2022 16:21:23 +0200 Subject: [PATCH 01/11] fix multi drop menu open when more than a topic tag clicked in same moment --- .../com/google/samples/apps/niacatalog/ui/Catalog.kt | 10 ++++++++-- .../nowinandroid/core/designsystem/component/Tag.kt | 8 +++++--- .../apps/nowinandroid/core/ui/NewsResourceCard.kt | 4 ++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/app-nia-catalog/src/main/java/com/google/samples/apps/niacatalog/ui/Catalog.kt b/app-nia-catalog/src/main/java/com/google/samples/apps/niacatalog/ui/Catalog.kt index d4d7b499b..9dc2d2fb2 100644 --- a/app-nia-catalog/src/main/java/com/google/samples/apps/niacatalog/ui/Catalog.kt +++ b/app-nia-catalog/src/main/java/com/google/samples/apps/niacatalog/ui/Catalog.kt @@ -518,24 +518,30 @@ fun NiaCatalog() { item { Text("Tags", Modifier.padding(top = 16.dp)) } item { FlowRow(mainAxisSpacing = 16.dp) { + var expandedTopic by remember { mutableStateOf(null) } + var firstFollowed by remember { mutableStateOf(false) } NiaTopicTag( + expanded = expandedTopic == "Topic 1", followed = firstFollowed, + onDropMenuToggle = { show -> expandedTopic = if (show) "Topic 1" else null }, onFollowClick = { firstFollowed = true }, onUnfollowClick = { firstFollowed = false }, onBrowseClick = {}, - text = { Text(text = "Topic".uppercase()) }, + text = { Text(text = "Topic 1".uppercase()) }, followText = { Text(text = "Follow") }, unFollowText = { Text(text = "Unfollow") }, browseText = { Text(text = "Browse topic") } ) var secondFollowed by remember { mutableStateOf(true) } NiaTopicTag( + expanded = expandedTopic == "Topic 2", followed = secondFollowed, + onDropMenuToggle = { show -> expandedTopic = if (show) "Topic 2" else null }, onFollowClick = { secondFollowed = true }, onUnfollowClick = { secondFollowed = false }, onBrowseClick = {}, - text = { Text(text = "Topic".uppercase()) }, + text = { Text(text = "Topic 2".uppercase()) }, followText = { Text(text = "Follow") }, unFollowText = { Text(text = "Unfollow") }, browseText = { Text(text = "Browse topic") } diff --git a/core-designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tag.kt b/core-designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tag.kt index d45bdb226..38a585907 100644 --- a/core-designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tag.kt +++ b/core-designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tag.kt @@ -32,7 +32,9 @@ import com.google.samples.apps.nowinandroid.core.designsystem.R @Composable fun NiaTopicTag( + expanded : Boolean = false, followed: Boolean, + onDropMenuToggle : (show: Boolean) -> Unit = {}, onFollowClick: () -> Unit, onUnfollowClick: () -> Unit, onBrowseClick: () -> Unit, @@ -43,7 +45,7 @@ fun NiaTopicTag( unFollowText: @Composable () -> Unit = { Text(stringResource(R.string.unfollow)) }, browseText: @Composable () -> Unit = { Text(stringResource(R.string.browse_topic)) } ) { - var expanded by remember { mutableStateOf(false) } + Box(modifier = modifier) { val containerColor = if (followed) { MaterialTheme.colorScheme.primaryContainer @@ -51,7 +53,7 @@ fun NiaTopicTag( MaterialTheme.colorScheme.surfaceVariant } NiaTextButton( - onClick = { expanded = true }, + onClick = { onDropMenuToggle(true) }, enabled = enabled, small = true, colors = NiaButtonDefaults.textButtonColors( @@ -69,7 +71,7 @@ fun NiaTopicTag( ) NiaDropdownMenu( expanded = expanded, - onDismissRequest = { expanded = false }, + onDismissRequest = { onDropMenuToggle(false) }, items = if (followed) listOf(UNFOLLOW, BROWSE) else listOf(FOLLOW, BROWSE), onItemClick = { item -> when (item) { diff --git a/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index 117b2ae47..d29d022c3 100644 --- a/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -268,13 +268,17 @@ fun NewsResourceTopics( topics: List, modifier: Modifier = Modifier ) { + var expandedTopic by remember { mutableStateOf(null) } + Row( modifier = modifier.horizontalScroll(rememberScrollState()), // causes narrow chips horizontalArrangement = Arrangement.spacedBy(4.dp), ) { for (topic in topics) { NiaTopicTag( + expanded = expandedTopic == topic.id, followed = true, // ToDo: Check if topic is followed + onDropMenuToggle = { show -> expandedTopic = if (show) topic.id else null }, onFollowClick = { }, // ToDo onUnfollowClick = { }, // ToDo onBrowseClick = { }, // ToDo From e13796b9ef8f19190023cc0f1254ee996e43410d Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 31 Aug 2022 17:24:29 +0200 Subject: [PATCH 02/11] fix ktlint error 'Exceeded max line length' --- .../java/com/google/samples/apps/niacatalog/ui/Catalog.kt | 8 ++++++-- .../samples/apps/nowinandroid/core/ui/NewsResourceCard.kt | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app-nia-catalog/src/main/java/com/google/samples/apps/niacatalog/ui/Catalog.kt b/app-nia-catalog/src/main/java/com/google/samples/apps/niacatalog/ui/Catalog.kt index 9dc2d2fb2..7f554b470 100644 --- a/app-nia-catalog/src/main/java/com/google/samples/apps/niacatalog/ui/Catalog.kt +++ b/app-nia-catalog/src/main/java/com/google/samples/apps/niacatalog/ui/Catalog.kt @@ -524,7 +524,9 @@ fun NiaCatalog() { NiaTopicTag( expanded = expandedTopic == "Topic 1", followed = firstFollowed, - onDropMenuToggle = { show -> expandedTopic = if (show) "Topic 1" else null }, + onDropMenuToggle = { show -> + expandedTopic = if (show) "Topic 1" else null + }, onFollowClick = { firstFollowed = true }, onUnfollowClick = { firstFollowed = false }, onBrowseClick = {}, @@ -537,7 +539,9 @@ fun NiaCatalog() { NiaTopicTag( expanded = expandedTopic == "Topic 2", followed = secondFollowed, - onDropMenuToggle = { show -> expandedTopic = if (show) "Topic 2" else null }, + onDropMenuToggle = { show -> + expandedTopic = if (show) "Topic 2" else null + }, onFollowClick = { secondFollowed = true }, onUnfollowClick = { secondFollowed = false }, onBrowseClick = {}, diff --git a/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index d29d022c3..00b6a0a93 100644 --- a/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -278,7 +278,9 @@ fun NewsResourceTopics( NiaTopicTag( expanded = expandedTopic == topic.id, followed = true, // ToDo: Check if topic is followed - onDropMenuToggle = { show -> expandedTopic = if (show) topic.id else null }, + onDropMenuToggle = { show -> + expandedTopic = if (show) topic.id else null + }, onFollowClick = { }, // ToDo onUnfollowClick = { }, // ToDo onBrowseClick = { }, // ToDo From ad323d2500be3f0db97faa987db3caa7da12bcb8 Mon Sep 17 00:00:00 2001 From: Jolanda Verhoef Date: Sun, 21 Aug 2022 13:05:29 +0100 Subject: [PATCH 03/11] Use GradleLocalProperties for reading warningsAsErrors from local.properties --- .../com/google/samples/apps/nowinandroid/KotlinAndroid.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt index ef9ec9072..bdcad8876 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt @@ -17,6 +17,7 @@ package com.google.samples.apps.nowinandroid import com.android.build.api.dsl.CommonExtension +import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties import org.gradle.api.JavaVersion import org.gradle.api.Project import org.gradle.api.artifacts.VersionCatalogsExtension @@ -46,7 +47,7 @@ internal fun Project.configureKotlinAndroid( kotlinOptions { // Treat all Kotlin warnings as errors (disabled by default) - allWarningsAsErrors = properties["warningsAsErrors"] as? Boolean ?: false + allWarningsAsErrors = gradleLocalProperties(rootDir).getProperty("warningsAsErrors").toBoolean() freeCompilerArgs = freeCompilerArgs + listOf( "-opt-in=kotlin.RequiresOptIn", From b5fab8e31d8a039fea7baca4ecd783c28bc4dfdc Mon Sep 17 00:00:00 2001 From: Jolanda Verhoef Date: Tue, 23 Aug 2022 12:56:41 +0100 Subject: [PATCH 04/11] Read warningsAsErrors from local.properties or gradle.properties, and default to false --- .github/ci-gradle.properties | 7 +++++-- .../google/samples/apps/nowinandroid/KotlinAndroid.kt | 9 ++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.github/ci-gradle.properties b/.github/ci-gradle.properties index 089f2a675..54bc49dcb 100644 --- a/.github/ci-gradle.properties +++ b/.github/ci-gradle.properties @@ -21,5 +21,8 @@ org.gradle.workers.max=2 kotlin.incremental=false kotlin.compiler.execution.strategy=in-process -# Controls KotlinOptions.allWarningsAsErrors. This is used in CI and can be set in local properties. -warningsAsErrors=true +# Controls KotlinOptions.allWarningsAsErrors. +# This value used in CI and is currently set to false. +# If you want to treat warnings as errors locally, set this property +# in local.properties. +warningsAsErrors=false diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt index bdcad8876..87d3e4b16 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt @@ -24,6 +24,7 @@ import org.gradle.api.artifacts.VersionCatalogsExtension import org.gradle.api.plugins.ExtensionAware import org.gradle.kotlin.dsl.dependencies import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.provideDelegate import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions /** @@ -47,7 +48,13 @@ internal fun Project.configureKotlinAndroid( kotlinOptions { // Treat all Kotlin warnings as errors (disabled by default) - allWarningsAsErrors = gradleLocalProperties(rootDir).getProperty("warningsAsErrors").toBoolean() + // Override locally using local.properties + val localOverrideWarningsAsErrors = gradleLocalProperties(rootDir) + .getProperty("warningsAsErrors")?.toBoolean() + // Set on CI through gradle.properties + val warningsAsErrors: Boolean? by project + // Prefer local.properties, gradle.properties, or default to false + allWarningsAsErrors = localOverrideWarningsAsErrors ?: warningsAsErrors ?: false freeCompilerArgs = freeCompilerArgs + listOf( "-opt-in=kotlin.RequiresOptIn", From b1789863f68cc4e102a678764b4bff2987066813 Mon Sep 17 00:00:00 2001 From: Jolanda Verhoef Date: Tue, 23 Aug 2022 13:34:01 +0100 Subject: [PATCH 05/11] Read gradle property as string instead of boolean, gradle sync fails otherwise. --- .github/ci-gradle.properties | 2 +- .../com/google/samples/apps/nowinandroid/KotlinAndroid.kt | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/ci-gradle.properties b/.github/ci-gradle.properties index 54bc49dcb..1cd5c8496 100644 --- a/.github/ci-gradle.properties +++ b/.github/ci-gradle.properties @@ -25,4 +25,4 @@ kotlin.compiler.execution.strategy=in-process # This value used in CI and is currently set to false. # If you want to treat warnings as errors locally, set this property # in local.properties. -warningsAsErrors=false +warningsAsErrors="false" diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt index 87d3e4b16..9df96c5cb 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt @@ -23,6 +23,7 @@ import org.gradle.api.Project import org.gradle.api.artifacts.VersionCatalogsExtension import org.gradle.api.plugins.ExtensionAware import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.extra import org.gradle.kotlin.dsl.getByType import org.gradle.kotlin.dsl.provideDelegate import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions @@ -52,9 +53,9 @@ internal fun Project.configureKotlinAndroid( val localOverrideWarningsAsErrors = gradleLocalProperties(rootDir) .getProperty("warningsAsErrors")?.toBoolean() // Set on CI through gradle.properties - val warningsAsErrors: Boolean? by project - // Prefer local.properties, gradle.properties, or default to false - allWarningsAsErrors = localOverrideWarningsAsErrors ?: warningsAsErrors ?: false + val warningsAsErrors: String? by project + // Prefer local.properties, gradle.properties, or default to false when both are null + allWarningsAsErrors = localOverrideWarningsAsErrors ?: warningsAsErrors.toBoolean() freeCompilerArgs = freeCompilerArgs + listOf( "-opt-in=kotlin.RequiresOptIn", From 69e88cc844c8ec7b8635aba2aa1224fd7a873e10 Mon Sep 17 00:00:00 2001 From: Jolanda Verhoef Date: Wed, 24 Aug 2022 17:42:21 +0100 Subject: [PATCH 06/11] Only use gradle.properties to read warningsAsErrors --- .github/ci-gradle.properties | 6 +++--- .../com/google/samples/apps/nowinandroid/KotlinAndroid.kt | 8 ++------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/.github/ci-gradle.properties b/.github/ci-gradle.properties index 1cd5c8496..bd989705d 100644 --- a/.github/ci-gradle.properties +++ b/.github/ci-gradle.properties @@ -23,6 +23,6 @@ kotlin.compiler.execution.strategy=in-process # Controls KotlinOptions.allWarningsAsErrors. # This value used in CI and is currently set to false. -# If you want to treat warnings as errors locally, set this property -# in local.properties. -warningsAsErrors="false" +# If you want to treat warnings as errors locally, set this property to true +# in your ~/.gradle/gradle.properties file. +warningsAsErrors=false diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt index 9df96c5cb..a0320f2a0 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt @@ -49,13 +49,9 @@ internal fun Project.configureKotlinAndroid( kotlinOptions { // Treat all Kotlin warnings as errors (disabled by default) - // Override locally using local.properties - val localOverrideWarningsAsErrors = gradleLocalProperties(rootDir) - .getProperty("warningsAsErrors")?.toBoolean() - // Set on CI through gradle.properties + // Override by setting warningsAsErrors=true in your ~/.gradle/gradle.properties val warningsAsErrors: String? by project - // Prefer local.properties, gradle.properties, or default to false when both are null - allWarningsAsErrors = localOverrideWarningsAsErrors ?: warningsAsErrors.toBoolean() + allWarningsAsErrors = warningsAsErrors.toBoolean() freeCompilerArgs = freeCompilerArgs + listOf( "-opt-in=kotlin.RequiresOptIn", From 9a4486b104ea47bcd3385387736d36e7e8c86ce3 Mon Sep 17 00:00:00 2001 From: Jolanda Verhoef Date: Wed, 24 Aug 2022 18:31:17 +0100 Subject: [PATCH 07/11] Remove unused imports --- .../com/google/samples/apps/nowinandroid/KotlinAndroid.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt index a0320f2a0..5dc7b987d 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinAndroid.kt @@ -17,13 +17,11 @@ package com.google.samples.apps.nowinandroid import com.android.build.api.dsl.CommonExtension -import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties import org.gradle.api.JavaVersion import org.gradle.api.Project import org.gradle.api.artifacts.VersionCatalogsExtension import org.gradle.api.plugins.ExtensionAware import org.gradle.kotlin.dsl.dependencies -import org.gradle.kotlin.dsl.extra import org.gradle.kotlin.dsl.getByType import org.gradle.kotlin.dsl.provideDelegate import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions From eaa0815ee818d311128947c7adb57e8015c2ab42 Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 31 Aug 2022 20:39:54 +0200 Subject: [PATCH 08/11] rename variable and fix spotless errors --- .../com/google/samples/apps/niacatalog/ui/Catalog.kt | 10 +++++----- .../nowinandroid/core/designsystem/component/Tag.kt | 8 ++------ .../apps/nowinandroid/core/ui/NewsResourceCard.kt | 8 +++++--- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/app-nia-catalog/src/main/java/com/google/samples/apps/niacatalog/ui/Catalog.kt b/app-nia-catalog/src/main/java/com/google/samples/apps/niacatalog/ui/Catalog.kt index 7f554b470..851c20b28 100644 --- a/app-nia-catalog/src/main/java/com/google/samples/apps/niacatalog/ui/Catalog.kt +++ b/app-nia-catalog/src/main/java/com/google/samples/apps/niacatalog/ui/Catalog.kt @@ -518,14 +518,14 @@ fun NiaCatalog() { item { Text("Tags", Modifier.padding(top = 16.dp)) } item { FlowRow(mainAxisSpacing = 16.dp) { - var expandedTopic by remember { mutableStateOf(null) } + var expandedTopicId by remember { mutableStateOf(null) } var firstFollowed by remember { mutableStateOf(false) } NiaTopicTag( - expanded = expandedTopic == "Topic 1", + expanded = expandedTopicId == "Topic 1", followed = firstFollowed, onDropMenuToggle = { show -> - expandedTopic = if (show) "Topic 1" else null + expandedTopicId = if (show) "Topic 1" else null }, onFollowClick = { firstFollowed = true }, onUnfollowClick = { firstFollowed = false }, @@ -537,10 +537,10 @@ fun NiaCatalog() { ) var secondFollowed by remember { mutableStateOf(true) } NiaTopicTag( - expanded = expandedTopic == "Topic 2", + expanded = expandedTopicId == "Topic 2", followed = secondFollowed, onDropMenuToggle = { show -> - expandedTopic = if (show) "Topic 2" else null + expandedTopicId = if (show) "Topic 2" else null }, onFollowClick = { secondFollowed = true }, onUnfollowClick = { secondFollowed = false }, diff --git a/core-designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tag.kt b/core-designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tag.kt index 38a585907..6a2475931 100644 --- a/core-designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tag.kt +++ b/core-designsystem/src/main/java/com/google/samples/apps/nowinandroid/core/designsystem/component/Tag.kt @@ -21,10 +21,6 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.material3.contentColorFor import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource @@ -32,9 +28,9 @@ import com.google.samples.apps.nowinandroid.core.designsystem.R @Composable fun NiaTopicTag( - expanded : Boolean = false, + expanded: Boolean = false, followed: Boolean, - onDropMenuToggle : (show: Boolean) -> Unit = {}, + onDropMenuToggle: (show: Boolean) -> Unit = {}, onFollowClick: () -> Unit, onUnfollowClick: () -> Unit, onBrowseClick: () -> Unit, diff --git a/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index 00b6a0a93..0b765bbc1 100644 --- a/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -268,7 +268,9 @@ fun NewsResourceTopics( topics: List, modifier: Modifier = Modifier ) { - var expandedTopic by remember { mutableStateOf(null) } + // Store the ID of the Topic which has its "following" menu expanded, if any. + // To avoid UI confusion, only one topic can have an expanded menu at a time. + var expandedTopicId by remember { mutableStateOf(null) } Row( modifier = modifier.horizontalScroll(rememberScrollState()), // causes narrow chips @@ -276,10 +278,10 @@ fun NewsResourceTopics( ) { for (topic in topics) { NiaTopicTag( - expanded = expandedTopic == topic.id, + expanded = expandedTopicId == topic.id, followed = true, // ToDo: Check if topic is followed onDropMenuToggle = { show -> - expandedTopic = if (show) topic.id else null + expandedTopicId = if (show) topic.id else null }, onFollowClick = { }, // ToDo onUnfollowClick = { }, // ToDo From d7711142b2493e319b70d248c4303c46912d2320 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 1 Sep 2022 16:04:15 +0000 Subject: [PATCH 09/11] Update androidxCompose to v1.2.1 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a54155f4f..83da2ec2a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,7 @@ androidDesugarJdkLibs = "1.1.5" androidGradlePlugin = "7.2.1" androidxActivity = "1.4.0" androidxAppCompat = "1.5.0" -androidxCompose = "1.2.0-rc03" +androidxCompose = "1.2.1" androidxComposeCompiler = "1.2.0" androidxComposeMaterial3 = "1.0.0-alpha13" androidxCore = "1.8.0" From 30f7f0ea3a37453a6ce49ae23e89ec45f8887f9f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 1 Sep 2022 21:51:01 +0000 Subject: [PATCH 10/11] Update dependency org.jetbrains.kotlinx:kotlinx-serialization-json to v1.4.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1f4ebf8a3..0529834ac 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -34,7 +34,7 @@ junit4 = "4.13.2" kotlin = "1.7.0" kotlinxCoroutines = "1.6.3" kotlinxDatetime = "0.4.0" -kotlinxSerializationJson = "1.3.3" +kotlinxSerializationJson = "1.4.0" ksp = "1.7.0-1.0.6" ktlint = "0.43.0" lint = "30.2.1" From 511f42c43820f0bff84f98194fb9fc610d0cb2c5 Mon Sep 17 00:00:00 2001 From: Hasan Zohrevand Date: Sun, 4 Sep 2022 23:17:58 +0430 Subject: [PATCH 11/11] Add episode_id index to NewsResourceEntity Change-Id: Ic31a50e84f536ea3914c55ccc19afbcbbbc17cb1 --- .../10.json | 455 ++++++++++++++++++ .../nowinandroid/core/database/NiaDatabase.kt | 3 +- .../core/database/model/NewsResourceEntity.kt | 4 + 3 files changed, 461 insertions(+), 1 deletion(-) create mode 100644 core-database/schemas/com.google.samples.apps.nowinandroid.core.database.NiaDatabase/10.json diff --git a/core-database/schemas/com.google.samples.apps.nowinandroid.core.database.NiaDatabase/10.json b/core-database/schemas/com.google.samples.apps.nowinandroid.core.database.NiaDatabase/10.json new file mode 100644 index 000000000..d8aef53ed --- /dev/null +++ b/core-database/schemas/com.google.samples.apps.nowinandroid.core.database.NiaDatabase/10.json @@ -0,0 +1,455 @@ +{ + "formatVersion": 1, + "database": { + "version": 10, + "identityHash": "d90e438da4b3b9cf552df536431dacb3", + "entities": [ + { + "tableName": "authors", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `image_url` TEXT NOT NULL, `twitter` TEXT NOT NULL DEFAULT '', `medium_page` TEXT NOT NULL DEFAULT '', `bio` TEXT NOT NULL DEFAULT '', PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "imageUrl", + "columnName": "image_url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "twitter", + "columnName": "twitter", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "mediumPage", + "columnName": "medium_page", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "bio", + "columnName": "bio", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "episodes_authors", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`episode_id` TEXT NOT NULL, `author_id` TEXT NOT NULL, PRIMARY KEY(`episode_id`, `author_id`), FOREIGN KEY(`episode_id`) REFERENCES `episodes`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`author_id`) REFERENCES `authors`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "episodeId", + "columnName": "episode_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "authorId", + "columnName": "author_id", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "episode_id", + "author_id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_episodes_authors_episode_id", + "unique": false, + "columnNames": [ + "episode_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_episodes_authors_episode_id` ON `${TABLE_NAME}` (`episode_id`)" + }, + { + "name": "index_episodes_authors_author_id", + "unique": false, + "columnNames": [ + "author_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_episodes_authors_author_id` ON `${TABLE_NAME}` (`author_id`)" + } + ], + "foreignKeys": [ + { + "table": "episodes", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "episode_id" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "authors", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "author_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "episodes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `publish_date` INTEGER NOT NULL, `alternate_video` TEXT, `alternate_audio` TEXT, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "publishDate", + "columnName": "publish_date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "alternateVideo", + "columnName": "alternate_video", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "alternateAudio", + "columnName": "alternate_audio", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "news_resources_authors", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`news_resource_id` TEXT NOT NULL, `author_id` TEXT NOT NULL, PRIMARY KEY(`news_resource_id`, `author_id`), FOREIGN KEY(`news_resource_id`) REFERENCES `news_resources`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`author_id`) REFERENCES `authors`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "newsResourceId", + "columnName": "news_resource_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "authorId", + "columnName": "author_id", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "news_resource_id", + "author_id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_news_resources_authors_news_resource_id", + "unique": false, + "columnNames": [ + "news_resource_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_news_resources_authors_news_resource_id` ON `${TABLE_NAME}` (`news_resource_id`)" + }, + { + "name": "index_news_resources_authors_author_id", + "unique": false, + "columnNames": [ + "author_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_news_resources_authors_author_id` ON `${TABLE_NAME}` (`author_id`)" + } + ], + "foreignKeys": [ + { + "table": "news_resources", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "news_resource_id" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "authors", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "author_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "news_resources", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `episode_id` TEXT NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `url` TEXT NOT NULL, `header_image_url` TEXT, `publish_date` INTEGER NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`id`), FOREIGN KEY(`episode_id`) REFERENCES `episodes`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "episodeId", + "columnName": "episode_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "headerImageUrl", + "columnName": "header_image_url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "publishDate", + "columnName": "publish_date", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_news_resources_episode_id", + "unique": false, + "columnNames": [ + "episode_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_news_resources_episode_id` ON `${TABLE_NAME}` (`episode_id`)" + } + ], + "foreignKeys": [ + { + "table": "episodes", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "episode_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "news_resources_topics", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`news_resource_id` TEXT NOT NULL, `topic_id` TEXT NOT NULL, PRIMARY KEY(`news_resource_id`, `topic_id`), FOREIGN KEY(`news_resource_id`) REFERENCES `news_resources`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`topic_id`) REFERENCES `topics`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "newsResourceId", + "columnName": "news_resource_id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "topicId", + "columnName": "topic_id", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "news_resource_id", + "topic_id" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_news_resources_topics_news_resource_id", + "unique": false, + "columnNames": [ + "news_resource_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_news_resources_topics_news_resource_id` ON `${TABLE_NAME}` (`news_resource_id`)" + }, + { + "name": "index_news_resources_topics_topic_id", + "unique": false, + "columnNames": [ + "topic_id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_news_resources_topics_topic_id` ON `${TABLE_NAME}` (`topic_id`)" + } + ], + "foreignKeys": [ + { + "table": "news_resources", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "news_resource_id" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "topics", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "topic_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "topics", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `shortDescription` TEXT NOT NULL, `longDescription` TEXT NOT NULL DEFAULT '', `url` TEXT NOT NULL DEFAULT '', `imageUrl` TEXT NOT NULL DEFAULT '', PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "shortDescription", + "columnName": "shortDescription", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "longDescription", + "columnName": "longDescription", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "imageUrl", + "columnName": "imageUrl", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd90e438da4b3b9cf552df536431dacb3')" + ] + } +} \ No newline at end of file diff --git a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/NiaDatabase.kt b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/NiaDatabase.kt index ebc7a075a..e367c4bca 100644 --- a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/NiaDatabase.kt +++ b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/NiaDatabase.kt @@ -44,7 +44,7 @@ import com.google.samples.apps.nowinandroid.core.database.util.NewsResourceTypeC NewsResourceTopicCrossRef::class, TopicEntity::class, ], - version = 9, + version = 10, autoMigrations = [ AutoMigration(from = 1, to = 2), AutoMigration(from = 2, to = 3, spec = DatabaseMigrations.Schema2to3::class), @@ -54,6 +54,7 @@ import com.google.samples.apps.nowinandroid.core.database.util.NewsResourceTypeC AutoMigration(from = 6, to = 7), AutoMigration(from = 7, to = 8), AutoMigration(from = 8, to = 9), + AutoMigration(from = 9, to = 10), ], exportSchema = true, ) diff --git a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceEntity.kt b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceEntity.kt index e74135f12..8d15a1f0b 100644 --- a/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceEntity.kt +++ b/core-database/src/main/java/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceEntity.kt @@ -19,6 +19,7 @@ package com.google.samples.apps.nowinandroid.core.database.model import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.ForeignKey +import androidx.room.Index import androidx.room.PrimaryKey import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType @@ -37,6 +38,9 @@ import kotlinx.datetime.Instant childColumns = ["episode_id"], onDelete = ForeignKey.CASCADE ), + ], + indices = [ + Index(value = ["episode_id"]) ] ) data class NewsResourceEntity(