From be2f1e98126ec19fdf5688008881523315ed0499 Mon Sep 17 00:00:00 2001 From: Mercury Li Date: Wed, 11 Feb 2026 18:37:42 -0800 Subject: [PATCH] Fix compilation warnings: upgrade kotlinx-datetime 0.7.1, migrate deprecated APIs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Upgrade kotlinx-datetime 0.6.1 → 0.7.1 and migrate to kotlin.time.Instant/Clock - Migrate TabRow → SecondaryTabRow with TabIndicatorScope API - Fix LocalDateTime constructors (monthNumber → month, dayOfMonth → day) - Remove deprecated KoinAndroidContext wrapper, add KOIN_DEFAULT_MODULE KSP arg - Convert SystemTrayNotifier expression body with return to block body - Add @param: annotation target prefix for @Dispatcher and @ApplicationScope - Add @ConsistentCopyVisibility to UserNewsResource data class - Fix JVM compilation: use correct uiToolingPreview dep, move lifecycle-runtime-compose to commonMain --- .../samples/apps/nowinandroid/MainActivity.kt | 5 +- .../util/ProfileVerifierLogger.kt | 2 +- .../main/kotlin/CmpFeatureConventionPlugin.kt | 2 +- .../src/main/kotlin/KoinConventionPlugin.kt | 4 + .../core/data/model/RecentSearchQuery.kt | 4 +- .../DefaultRecentSearchRepository.kt | 2 +- .../DefaultSearchContentsRepository.kt | 2 +- ...CompositeUserNewsResourceRepositoryTest.kt | 2 +- .../core/data/UserNewsResourceTest.kt | 2 +- .../core/data/model/NetworkEntityTest.kt | 2 +- .../model/PopulatedNewsResourceKtTest.kt | 2 +- .../core/database/dao/NewsResourceDao.kt | 2 +- .../core/database/dao/RecentSearchQueryDao.kt | 2 +- .../core/database/model/NewsResourceEntity.kt | 2 +- .../database/model/RecentSearchQueryEntity.kt | 2 +- .../core/database/util/InstantConverter.kt | 2 +- .../core/database/dao/NewsResourceDaoTest.kt | 2 +- .../datastore/NiaPreferencesDataSource.kt | 2 +- .../core/designsystem/component/Tabs.kt | 11 ++- .../core/model/data/NewsResource.kt | 2 +- .../core/model/data/UserNewsResource.kt | 3 +- .../network/demo/DemoNiaNetworkDataSource.kt | 2 +- .../core/network/model/NetworkNewsResource.kt | 2 +- .../demo/DemoNiaNetworkDataSourceTest.kt | 5 +- .../core/notifications/SystemTrayNotifier.kt | 78 ++++++++++--------- .../testing/data/NewsResourcesTestData.kt | 2 +- .../testing/data/UserNewsResourcesTestData.kt | 7 +- core/ui/build.gradle.kts | 2 +- .../nowinandroid/core/ui/NewsResourceCard.kt | 2 +- ...serNewsResourcePreviewParameterProvider.kt | 7 +- .../feature/foryou/ForYouViewModelTest.kt | 2 +- .../feature/topic/TopicViewModelTest.kt | 2 +- gradle/libs.versions.toml | 2 +- 33 files changed, 89 insertions(+), 83 deletions(-) diff --git a/app/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt b/app/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt index efe6d512e..a68380b08 100644 --- a/app/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt +++ b/app/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/MainActivity.kt @@ -48,7 +48,6 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import org.koin.android.ext.android.inject -import org.koin.androidx.compose.KoinAndroidContext import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.core.parameter.parametersOf @@ -144,9 +143,7 @@ class MainActivity : ComponentActivity() { androidTheme = themeSettings.androidTheme, disableDynamicTheming = themeSettings.disableDynamicTheming, ) { - KoinAndroidContext { - NiaApp(appState) - } + NiaApp(appState) } } } diff --git a/app/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/util/ProfileVerifierLogger.kt b/app/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/util/ProfileVerifierLogger.kt index b4bdcd3ac..bb33030d9 100644 --- a/app/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/util/ProfileVerifierLogger.kt +++ b/app/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/util/ProfileVerifierLogger.kt @@ -48,7 +48,7 @@ import kotlinx.coroutines.launch * @see androidx.profileinstaller.ProfileVerifier.CompilationStatus.ResultCode */ class ProfileVerifierLogger( - @ApplicationScope private val scope: CoroutineScope, + @param:ApplicationScope private val scope: CoroutineScope, ) { companion object { private const val TAG = "ProfileInstaller" diff --git a/build-logic/convention/src/main/kotlin/CmpFeatureConventionPlugin.kt b/build-logic/convention/src/main/kotlin/CmpFeatureConventionPlugin.kt index e60bc0aa0..696740c81 100644 --- a/build-logic/convention/src/main/kotlin/CmpFeatureConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/CmpFeatureConventionPlugin.kt @@ -52,7 +52,7 @@ class CmpFeatureConventionPlugin : Plugin { "commonMainImplementation"(libs.findLibrary("koin.compose.viewmodel").get()) "commonMainImplementation"(libs.findLibrary("koin.compose.viewmodel.navigation").get()) - "androidMainImplementation"(libs.findLibrary("androidx.lifecycle.runtimeCompose").get()) + "commonMainImplementation"(libs.findLibrary("androidx.lifecycle.runtimeCompose").get()) "androidMainImplementation"(libs.findLibrary("androidx.tracing.ktx").get()) "androidInstrumentedTestImplementation"(libs.findLibrary("androidx.compose.ui.test").get()) diff --git a/build-logic/convention/src/main/kotlin/KoinConventionPlugin.kt b/build-logic/convention/src/main/kotlin/KoinConventionPlugin.kt index 61894022a..0d62437f8 100644 --- a/build-logic/convention/src/main/kotlin/KoinConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/KoinConventionPlugin.kt @@ -28,6 +28,10 @@ class KoinConventionPlugin : Plugin { apply("com.google.devtools.ksp") } + extensions.configure(com.google.devtools.ksp.gradle.KspExtension::class.java) { + arg("KOIN_DEFAULT_MODULE", "true") + } + extensions.configure(KotlinMultiplatformExtension::class.java) { sourceSets.named("commonMain").configure { kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin") diff --git a/core/data/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/data/model/RecentSearchQuery.kt b/core/data/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/data/model/RecentSearchQuery.kt index 76dd08811..0739f6083 100644 --- a/core/data/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/data/model/RecentSearchQuery.kt +++ b/core/data/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/data/model/RecentSearchQuery.kt @@ -17,8 +17,8 @@ package com.google.samples.apps.nowinandroid.core.data.model import com.google.samples.apps.nowinandroid.core.database.model.RecentSearchQueryEntity -import kotlinx.datetime.Clock -import kotlinx.datetime.Instant +import kotlin.time.Clock +import kotlin.time.Instant data class RecentSearchQuery( val query: String, diff --git a/core/data/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/DefaultRecentSearchRepository.kt b/core/data/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/DefaultRecentSearchRepository.kt index a3306cc1a..585437294 100644 --- a/core/data/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/DefaultRecentSearchRepository.kt +++ b/core/data/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/DefaultRecentSearchRepository.kt @@ -22,7 +22,7 @@ import com.google.samples.apps.nowinandroid.core.database.dao.RecentSearchQueryD import com.google.samples.apps.nowinandroid.core.database.model.RecentSearchQueryEntity import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map -import kotlinx.datetime.Clock +import kotlin.time.Clock class DefaultRecentSearchRepository( private val recentSearchQueryDao: RecentSearchQueryDao, diff --git a/core/data/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/DefaultSearchContentsRepository.kt b/core/data/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/DefaultSearchContentsRepository.kt index b1b900090..17bce1b6c 100644 --- a/core/data/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/DefaultSearchContentsRepository.kt +++ b/core/data/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/DefaultSearchContentsRepository.kt @@ -42,7 +42,7 @@ class DefaultSearchContentsRepository( private val newsResourceFtsDao: NewsResourceFtsDao, private val topicDao: TopicDao, private val topicFtsDao: TopicFtsDao, - @Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher, + @param:Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher, ) : SearchContentsRepository { override suspend fun populateFtsData() { diff --git a/core/data/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/data/CompositeUserNewsResourceRepositoryTest.kt b/core/data/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/data/CompositeUserNewsResourceRepositoryTest.kt index f4786485c..e8131004e 100644 --- a/core/data/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/data/CompositeUserNewsResourceRepositoryTest.kt +++ b/core/data/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/data/CompositeUserNewsResourceRepositoryTest.kt @@ -26,9 +26,9 @@ import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserData import com.google.samples.apps.nowinandroid.core.testing.repository.emptyUserData import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runTest -import kotlinx.datetime.Instant import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.time.Instant class CompositeUserNewsResourceRepositoryTest { diff --git a/core/data/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/data/UserNewsResourceTest.kt b/core/data/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/data/UserNewsResourceTest.kt index 0623a4632..00ccb03bc 100644 --- a/core/data/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/data/UserNewsResourceTest.kt +++ b/core/data/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/data/UserNewsResourceTest.kt @@ -23,10 +23,10 @@ import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand.DEFAULT import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.model.data.UserData import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource -import kotlinx.datetime.Clock import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue +import kotlin.time.Clock class UserNewsResourceTest { diff --git a/core/data/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/data/model/NetworkEntityTest.kt b/core/data/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/data/model/NetworkEntityTest.kt index 52dbe5117..fd05548f7 100644 --- a/core/data/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/data/model/NetworkEntityTest.kt +++ b/core/data/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/data/model/NetworkEntityTest.kt @@ -21,9 +21,9 @@ import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.network.model.NetworkNewsResource import com.google.samples.apps.nowinandroid.core.network.model.NetworkTopic import com.google.samples.apps.nowinandroid.core.network.model.asExternalModel -import kotlinx.datetime.Instant import org.junit.Test import kotlin.test.assertEquals +import kotlin.time.Instant class NetworkEntityTest { diff --git a/core/data/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/database/model/PopulatedNewsResourceKtTest.kt b/core/data/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/database/model/PopulatedNewsResourceKtTest.kt index 3437d0c25..dc8ad8aea 100644 --- a/core/data/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/database/model/PopulatedNewsResourceKtTest.kt +++ b/core/data/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/database/model/PopulatedNewsResourceKtTest.kt @@ -18,9 +18,9 @@ package com.google.samples.apps.nowinandroid.core.database.model import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.Topic -import kotlinx.datetime.Instant import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.time.Instant class PopulatedNewsResourceKtTest { @Test diff --git a/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt b/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt index 372119cf4..f5e6b0fbc 100644 --- a/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt +++ b/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt @@ -25,7 +25,7 @@ import com.google.samples.apps.nowinandroid.core.database.model.PopulatedNewsRes import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow -import kotlinx.datetime.Instant +import kotlin.time.Instant /** * DAO for [NewsResource] and [NewsResourceEntity] access diff --git a/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/RecentSearchQueryDao.kt b/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/RecentSearchQueryDao.kt index b1b005a2c..97369a5a6 100644 --- a/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/RecentSearchQueryDao.kt +++ b/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/RecentSearchQueryDao.kt @@ -23,7 +23,7 @@ import com.google.samples.apps.nowinandroid.core.database.Recent_search_query import com.google.samples.apps.nowinandroid.core.database.model.RecentSearchQueryEntity import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow -import kotlinx.datetime.Instant +import kotlin.time.Instant /** * DAO for [RecentSearchQueryEntity] access diff --git a/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceEntity.kt b/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceEntity.kt index 175d46326..ce8b07651 100644 --- a/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceEntity.kt +++ b/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/model/NewsResourceEntity.kt @@ -17,7 +17,7 @@ package com.google.samples.apps.nowinandroid.core.database.model import com.google.samples.apps.nowinandroid.core.model.data.NewsResource -import kotlinx.datetime.Instant +import kotlin.time.Instant /** * Defines an NiA news resource. diff --git a/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/model/RecentSearchQueryEntity.kt b/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/model/RecentSearchQueryEntity.kt index 24318d3de..668379c37 100644 --- a/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/model/RecentSearchQueryEntity.kt +++ b/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/model/RecentSearchQueryEntity.kt @@ -16,7 +16,7 @@ package com.google.samples.apps.nowinandroid.core.database.model -import kotlinx.datetime.Instant +import kotlin.time.Instant /** * Defines an database entity that stored recent search queries. diff --git a/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/util/InstantConverter.kt b/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/util/InstantConverter.kt index e2082f4c3..2b2f41ff6 100644 --- a/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/util/InstantConverter.kt +++ b/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/util/InstantConverter.kt @@ -16,7 +16,7 @@ package com.google.samples.apps.nowinandroid.core.database.util -import kotlinx.datetime.Instant +import kotlin.time.Instant internal class InstantConverter { diff --git a/core/database/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt b/core/database/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt index bb647e13b..e75e453e3 100644 --- a/core/database/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt +++ b/core/database/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt @@ -25,9 +25,9 @@ import com.google.samples.apps.nowinandroid.core.database.model.asExternalModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runTest -import kotlinx.datetime.Instant import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.time.Instant class NewsResourceDaoTest { private lateinit var newsResourceDao: NewsResourceDao diff --git a/core/datastore/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSource.kt b/core/datastore/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSource.kt index 4e2e1849a..8d1a125ab 100644 --- a/core/datastore/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSource.kt +++ b/core/datastore/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/datastore/NiaPreferencesDataSource.kt @@ -37,7 +37,7 @@ private const val USER_DATA_KEY = "userData" @OptIn(ExperimentalSerializationApi::class, ExperimentalSettingsApi::class) class NiaPreferencesDataSource( private val settings: Settings, - @Dispatcher(IO) private val dispatcher: CoroutineDispatcher, + @param:Dispatcher(IO) private val dispatcher: CoroutineDispatcher, ) { // FlowSettings did not support JS, use a workaround instead // https://github.com/russhwolf/multiplatform-settings/issues/139 diff --git a/core/designsystem/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Tabs.kt b/core/designsystem/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Tabs.kt index 74753ca9b..a0664c1d5 100644 --- a/core/designsystem/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Tabs.kt +++ b/core/designsystem/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/designsystem/component/Tabs.kt @@ -20,10 +20,9 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.padding import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ProvideTextStyle +import androidx.compose.material3.SecondaryTabRow 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 @@ -72,7 +71,7 @@ fun NiaTab( } /** - * Now in Android tab row. Wraps Material 3 [TabRow]. + * Now in Android tab row. Wraps Material 3 [SecondaryTabRow]. * * @param selectedTabIndex The index of the currently selected tab. * @param modifier Modifier to be applied to the tab row. @@ -85,14 +84,14 @@ fun NiaTabRow( modifier: Modifier = Modifier, tabs: @Composable () -> Unit, ) { - TabRow( + SecondaryTabRow( selectedTabIndex = selectedTabIndex, modifier = modifier, containerColor = Color.Transparent, contentColor = MaterialTheme.colorScheme.onSurface, - indicator = { tabPositions -> + indicator = { TabRowDefaults.SecondaryIndicator( - modifier = Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex]), + modifier = Modifier.tabIndicatorOffset(selectedTabIndex), height = 2.dp, color = MaterialTheme.colorScheme.onSurface, ) diff --git a/core/model/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/model/data/NewsResource.kt b/core/model/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/model/data/NewsResource.kt index 996851ff3..5becaf9b9 100644 --- a/core/model/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/model/data/NewsResource.kt +++ b/core/model/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/model/data/NewsResource.kt @@ -16,7 +16,7 @@ package com.google.samples.apps.nowinandroid.core.model.data -import kotlinx.datetime.Instant +import kotlin.time.Instant /** * External data layer representation of a fully populated NiA news resource diff --git a/core/model/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/model/data/UserNewsResource.kt b/core/model/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/model/data/UserNewsResource.kt index a56bbcb8d..f312d45aa 100644 --- a/core/model/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/model/data/UserNewsResource.kt +++ b/core/model/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/model/data/UserNewsResource.kt @@ -16,12 +16,13 @@ package com.google.samples.apps.nowinandroid.core.model.data -import kotlinx.datetime.Instant +import kotlin.time.Instant /** * A [NewsResource] with additional user information such as whether the user is following the * news resource's topics and whether they have saved (bookmarked) this news resource. */ +@ConsistentCopyVisibility data class UserNewsResource internal constructor( val id: String, val title: String, diff --git a/core/network/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt b/core/network/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt index 1fe677105..51e39a0dd 100644 --- a/core/network/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt +++ b/core/network/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt @@ -34,7 +34,7 @@ import org.koin.core.annotation.Single */ @Single class DemoNiaNetworkDataSource( - @Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher, + @param:Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher, private val networkJson: Json, ) : NiaNetworkDataSource { diff --git a/core/network/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/model/NetworkNewsResource.kt b/core/network/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/model/NetworkNewsResource.kt index 64621469b..66a7f2921 100644 --- a/core/network/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/model/NetworkNewsResource.kt +++ b/core/network/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/model/NetworkNewsResource.kt @@ -17,8 +17,8 @@ package com.google.samples.apps.nowinandroid.core.network.model import com.google.samples.apps.nowinandroid.core.model.data.NewsResource -import kotlinx.datetime.Instant import kotlinx.serialization.Serializable +import kotlin.time.Instant /** * Network representation of [NewsResource] when fetched from /newsresources diff --git a/core/network/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSourceTest.kt b/core/network/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSourceTest.kt index e7fda79db..3c258da03 100644 --- a/core/network/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSourceTest.kt +++ b/core/network/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSourceTest.kt @@ -21,6 +21,7 @@ import com.google.samples.apps.nowinandroid.core.network.model.NetworkTopic import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.runTest import kotlinx.datetime.LocalDateTime +import kotlinx.datetime.Month import kotlinx.datetime.TimeZone import kotlinx.datetime.toInstant import kotlinx.serialization.json.Json @@ -70,8 +71,8 @@ class DemoNiaNetworkDataSourceTest { headerImageUrl = "https://developer.android.com/images/hero-assets/android-basics-compose.svg", publishDate = LocalDateTime( year = 2022, - monthNumber = 5, - dayOfMonth = 4, + month = Month.MAY, + day = 4, hour = 23, minute = 0, second = 0, diff --git a/core/notifications/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/notifications/SystemTrayNotifier.kt b/core/notifications/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/notifications/SystemTrayNotifier.kt index c2a322ee5..606077897 100644 --- a/core/notifications/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/notifications/SystemTrayNotifier.kt +++ b/core/notifications/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/notifications/SystemTrayNotifier.kt @@ -51,52 +51,54 @@ internal class SystemTrayNotifier constructor( override fun postNewsNotifications( newsResources: List, - ) = with(context) { - if (checkSelfPermission(this, permission.POST_NOTIFICATIONS) != PERMISSION_GRANTED) { - return - } + ) { + with(context) { + if (checkSelfPermission(this, permission.POST_NOTIFICATIONS) != PERMISSION_GRANTED) { + return + } - val truncatedNewsResources = newsResources.take(MAX_NUM_NOTIFICATIONS) + val truncatedNewsResources = newsResources.take(MAX_NUM_NOTIFICATIONS) - val newsNotifications = truncatedNewsResources.map { newsResource -> - createNewsNotification { - setSmallIcon( - com.google.samples.apps.nowinandroid.core.common.R.drawable.core_common_ic_nia_notification, + val newsNotifications = truncatedNewsResources.map { newsResource -> + createNewsNotification { + setSmallIcon( + com.google.samples.apps.nowinandroid.core.common.R.drawable.core_common_ic_nia_notification, + ) + .setContentTitle(newsResource.title) + .setContentText(newsResource.content) + .setContentIntent(newsPendingIntent(newsResource)) + .setGroup(NEWS_NOTIFICATION_GROUP) + .setAutoCancel(true) + } + } + val summaryNotification = createNewsNotification { + val title = getString( + R.string.core_notifications_news_notification_group_summary, + truncatedNewsResources.size, ) - .setContentTitle(newsResource.title) - .setContentText(newsResource.content) - .setContentIntent(newsPendingIntent(newsResource)) + setContentTitle(title) + .setContentText(title) + .setSmallIcon( + com.google.samples.apps.nowinandroid.core.common.R.drawable.core_common_ic_nia_notification, + ) + // Build summary info into InboxStyle template. + .setStyle(newsNotificationStyle(truncatedNewsResources, title)) .setGroup(NEWS_NOTIFICATION_GROUP) + .setGroupSummary(true) .setAutoCancel(true) + .build() } - } - val summaryNotification = createNewsNotification { - val title = getString( - R.string.core_notifications_news_notification_group_summary, - truncatedNewsResources.size, - ) - setContentTitle(title) - .setContentText(title) - .setSmallIcon( - com.google.samples.apps.nowinandroid.core.common.R.drawable.core_common_ic_nia_notification, - ) - // Build summary info into InboxStyle template. - .setStyle(newsNotificationStyle(truncatedNewsResources, title)) - .setGroup(NEWS_NOTIFICATION_GROUP) - .setGroupSummary(true) - .setAutoCancel(true) - .build() - } - // Send the notifications - val notificationManager = NotificationManagerCompat.from(this) - newsNotifications.forEachIndexed { index, notification -> - notificationManager.notify( - truncatedNewsResources[index].id.hashCode(), - notification, - ) + // Send the notifications + val notificationManager = NotificationManagerCompat.from(this) + newsNotifications.forEachIndexed { index, notification -> + notificationManager.notify( + truncatedNewsResources[index].id.hashCode(), + notification, + ) + } + notificationManager.notify(NEWS_NOTIFICATION_SUMMARY_ID, summaryNotification) } - notificationManager.notify(NEWS_NOTIFICATION_SUMMARY_ID, summaryNotification) } /** diff --git a/core/testing/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/testing/data/NewsResourcesTestData.kt b/core/testing/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/testing/data/NewsResourcesTestData.kt index b3fff7ca0..b468a1272 100644 --- a/core/testing/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/testing/data/NewsResourcesTestData.kt +++ b/core/testing/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/testing/data/NewsResourcesTestData.kt @@ -19,7 +19,7 @@ package com.google.samples.apps.nowinandroid.core.testing.data import com.google.samples.apps.nowinandroid.core.model.data.NewsResource -import kotlinx.datetime.Instant +import kotlin.time.Instant val newsResourcesTestData: List = listOf( NewsResource( diff --git a/core/testing/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/testing/data/UserNewsResourcesTestData.kt b/core/testing/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/testing/data/UserNewsResourcesTestData.kt index 4174391df..8d48f4071 100644 --- a/core/testing/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/testing/data/UserNewsResourcesTestData.kt +++ b/core/testing/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/testing/data/UserNewsResourcesTestData.kt @@ -23,10 +23,11 @@ import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand import com.google.samples.apps.nowinandroid.core.model.data.UserData import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource -import kotlinx.datetime.Instant import kotlinx.datetime.LocalDateTime +import kotlinx.datetime.Month import kotlinx.datetime.TimeZone import kotlinx.datetime.toInstant +import kotlin.time.Instant val userNewsResourcesTestData: List = UserData( bookmarkedNewsResources = setOf("1", "4"), @@ -47,8 +48,8 @@ val userNewsResourcesTestData: List = UserData( headerImageUrl = "https://developer.android.com/images/hero-assets/android-basics-compose.svg", publishDate = LocalDateTime( year = 2022, - monthNumber = 5, - dayOfMonth = 4, + month = Month.MAY, + day = 4, hour = 23, minute = 0, second = 0, diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts index 04574383f..03548d9ba 100644 --- a/core/ui/build.gradle.kts +++ b/core/ui/build.gradle.kts @@ -38,7 +38,7 @@ kotlin { implementation(libs.coil.compose) implementation(libs.jetbrains.compose.material3) implementation(libs.jetbrains.compose.components.resources) - implementation(libs.jetbrains.compose.components.uiToolingPreview) + implementation(libs.jetbrains.compose.uiToolingPreview) } androidInstrumentedTest.dependencies { implementation(projects.core.testing) diff --git a/core/ui/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index eee21e636..dbb259e1e 100644 --- a/core/ui/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core/ui/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -67,7 +67,6 @@ import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource -import kotlinx.datetime.Instant import nowinandroid.core.ui.generated.resources.Res import nowinandroid.core.ui.generated.resources.core_ui_bookmark import nowinandroid.core.ui.generated.resources.core_ui_card_meta_data_text @@ -79,6 +78,7 @@ import nowinandroid.core.ui.generated.resources.core_ui_topic_chip_content_descr import nowinandroid.core.ui.generated.resources.core_ui_unbookmark import nowinandroid.core.ui.generated.resources.core_ui_unread_resource_dot_content_description import org.jetbrains.compose.resources.stringResource +import kotlin.time.Instant /** * [NewsResource] card used on the following screens: For You, Saved diff --git a/core/ui/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/ui/UserNewsResourcePreviewParameterProvider.kt b/core/ui/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/ui/UserNewsResourcePreviewParameterProvider.kt index 3189e8403..e75fd1bb7 100644 --- a/core/ui/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/ui/UserNewsResourcePreviewParameterProvider.kt +++ b/core/ui/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/ui/UserNewsResourcePreviewParameterProvider.kt @@ -26,10 +26,11 @@ import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.model.data.UserData import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource import com.google.samples.apps.nowinandroid.core.ui.PreviewParameterData.newsResources -import kotlinx.datetime.Instant import kotlinx.datetime.LocalDateTime +import kotlinx.datetime.Month import kotlinx.datetime.TimeZone import kotlinx.datetime.toInstant +import kotlin.time.Instant /** * This [PreviewParameterProvider](https://developer.android.com/reference/kotlin/androidx/compose/ui/tooling/preview/PreviewParameterProvider) @@ -89,8 +90,8 @@ object PreviewParameterData { headerImageUrl = "https://developer.android.com/images/hero-assets/android-basics-compose.svg", publishDate = LocalDateTime( year = 2022, - monthNumber = 5, - dayOfMonth = 4, + month = Month.MAY, + day = 4, hour = 23, minute = 0, second = 0, diff --git a/feature/foryou/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt b/feature/foryou/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt index 812544c0c..beae5f439 100644 --- a/feature/foryou/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt +++ b/feature/foryou/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt @@ -41,13 +41,13 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest -import kotlinx.datetime.Instant import org.junit.Before import org.junit.Rule import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertNull import kotlin.test.assertTrue +import kotlin.time.Instant /** * To learn more about how this test handles Flows created with stateIn, see diff --git a/feature/topic/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt b/feature/topic/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt index 34f21a59a..834082da6 100644 --- a/feature/topic/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt +++ b/feature/topic/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/feature/topic/TopicViewModelTest.kt @@ -33,7 +33,6 @@ import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest -import kotlinx.datetime.Instant import org.junit.Before import org.junit.Rule import org.junit.Test @@ -41,6 +40,7 @@ import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner import kotlin.test.assertEquals import kotlin.test.assertIs +import kotlin.time.Instant /** * To learn more about how this test handles Flows created with stateIn, see diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0ec96a700..4418c42e6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -31,7 +31,7 @@ dependencyGuard = "0.5.0" jacoco = "0.8.12" kotlin = "2.3.10" kotlinxCoroutines = "1.10.2" -kotlinxDatetime = "0.6.1" +kotlinxDatetime = "0.7.1" kotlinxSerializationJson = "1.8.0" ksp = "2.3.5" logback = "1.5.15"