diff --git a/core/common/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/di/AndroidDispatchersComponent.kt b/core/common/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/di/AndroidDispatchersComponent.kt index 0421b2b55..8c4aaf877 100644 --- a/core/common/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/di/AndroidDispatchersComponent.kt +++ b/core/common/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/di/AndroidDispatchersComponent.kt @@ -16,6 +16,9 @@ package com.google.samples.apps.nowinandroid.core.di +import com.google.samples.apps.nowinandroid.core.di.NiaDispatchers.DEFAULT +import com.google.samples.apps.nowinandroid.core.di.NiaDispatchers.IO +import com.google.samples.apps.nowinandroid.core.di.NiaDispatchers.MAIN import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import me.tatarka.inject.annotations.Component @@ -24,9 +27,18 @@ import me.tatarka.inject.annotations.Provides @Component abstract class AndroidDispatchersComponent : DispatchersComponent() { @Provides - override fun providesIODispatcher(): @IoDispatcher CoroutineDispatcher = Dispatchers.IO + override fun providesIODispatcher(): + @Dispatcher(IO) + CoroutineDispatcher = Dispatchers.IO @Provides - override fun providesDefaultDispatcher(): @DefaultDispatcher CoroutineDispatcher = + override fun providesDefaultDispatcher(): + @Dispatcher(DEFAULT) + CoroutineDispatcher = Dispatchers.Default + + @Provides + override fun providesMainDispatcher(): + @Dispatcher(MAIN) + CoroutineDispatcher = Dispatchers.Main } diff --git a/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/CoroutineScopeComponent.kt b/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/CoroutineScopeComponent.kt index a10a19c69..afe01ee99 100644 --- a/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/CoroutineScopeComponent.kt +++ b/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/CoroutineScopeComponent.kt @@ -16,6 +16,7 @@ package com.google.samples.apps.nowinandroid.core.di +import com.google.samples.apps.nowinandroid.core.di.NiaDispatchers.DEFAULT import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob @@ -33,9 +34,10 @@ annotation class ApplicationScope abstract class CoroutineScopeComponent( @Component val dispatchersComponent: DispatchersComponent, ) { - @DefaultDispatcher abstract val defaultDispatcher: CoroutineDispatcher + @Dispatcher(DEFAULT) + abstract val dispatcher: CoroutineDispatcher @Provides fun providesCoroutineScope(): CoroutineScope = - CoroutineScope(SupervisorJob() + defaultDispatcher) + CoroutineScope(SupervisorJob() + dispatcher) } diff --git a/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt b/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt index 95cc4e8be..60f5782e4 100644 --- a/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt +++ b/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt @@ -16,13 +16,26 @@ package com.google.samples.apps.nowinandroid.core.di +import com.google.samples.apps.nowinandroid.core.di.NiaDispatchers.DEFAULT +import com.google.samples.apps.nowinandroid.core.di.NiaDispatchers.IO +import com.google.samples.apps.nowinandroid.core.di.NiaDispatchers.MAIN import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.IO import me.tatarka.inject.annotations.Provides abstract class DispatchersComponent { @Provides - abstract fun providesIODispatcher(): @IoDispatcher CoroutineDispatcher + abstract fun providesIODispatcher(): + @Dispatcher(IO) + CoroutineDispatcher @Provides - abstract fun providesDefaultDispatcher(): @DefaultDispatcher CoroutineDispatcher + abstract fun providesDefaultDispatcher(): + @Dispatcher(DEFAULT) + CoroutineDispatcher + + @Provides + abstract fun providesMainDispatcher(): + @Dispatcher(MAIN) + CoroutineDispatcher } diff --git a/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatcherQualifier.kt b/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/NiaDispatcher.kt similarity index 65% rename from core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatcherQualifier.kt rename to core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/NiaDispatcher.kt index 23cb66353..668d59a20 100644 --- a/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatcherQualifier.kt +++ b/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/NiaDispatcher.kt @@ -17,8 +17,10 @@ package com.google.samples.apps.nowinandroid.core.di import me.tatarka.inject.annotations.Qualifier +import kotlin.annotation.AnnotationRetention.RUNTIME @Qualifier +@Retention(RUNTIME) @Target( AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.FUNCTION, @@ -26,24 +28,10 @@ import me.tatarka.inject.annotations.Qualifier AnnotationTarget.TYPE, AnnotationTarget.PROPERTY, ) -annotation class IoDispatcher +annotation class Dispatcher(val dispatcher: NiaDispatchers) -@Qualifier -@Target( - AnnotationTarget.PROPERTY_GETTER, - AnnotationTarget.FUNCTION, - AnnotationTarget.VALUE_PARAMETER, - AnnotationTarget.TYPE, - AnnotationTarget.PROPERTY, -) -annotation class MainDispatcher - -@Qualifier -@Target( - AnnotationTarget.PROPERTY_GETTER, - AnnotationTarget.FUNCTION, - AnnotationTarget.VALUE_PARAMETER, - AnnotationTarget.TYPE, - AnnotationTarget.PROPERTY, -) -annotation class DefaultDispatcher +enum class NiaDispatchers { + IO, + DEFAULT, + MAIN, +} diff --git a/core/common/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/di/JvmDispatchersComponent.kt b/core/common/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/di/JvmDispatchersComponent.kt index c6df8a244..08ac30090 100644 --- a/core/common/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/di/JvmDispatchersComponent.kt +++ b/core/common/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/di/JvmDispatchersComponent.kt @@ -16,6 +16,9 @@ package com.google.samples.apps.nowinandroid.core.di +import com.google.samples.apps.nowinandroid.core.di.NiaDispatchers.DEFAULT +import com.google.samples.apps.nowinandroid.core.di.NiaDispatchers.IO +import com.google.samples.apps.nowinandroid.core.di.NiaDispatchers.MAIN import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import me.tatarka.inject.annotations.Component @@ -24,8 +27,17 @@ import me.tatarka.inject.annotations.Provides @Component abstract class JvmDispatchersComponent : DispatchersComponent() { @Provides - override fun providesIODispatcher(): @IoDispatcher CoroutineDispatcher = Dispatchers.IO + override fun providesIODispatcher(): + @Dispatcher(IO) + CoroutineDispatcher = Dispatchers.IO @Provides - override fun providesDefaultDispatcher(): @DefaultDispatcher CoroutineDispatcher = Dispatchers.Default + override fun providesDefaultDispatcher(): + @Dispatcher(DEFAULT) + CoroutineDispatcher = Dispatchers.Default + + @Provides + override fun providesMainDispatcher(): + @Dispatcher(MAIN) + CoroutineDispatcher = Dispatchers.Main } diff --git a/core/common/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/di/NativeDispatchersComponent.kt b/core/common/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/di/NativeDispatchersComponent.kt index 16cfd5a91..dde117d16 100644 --- a/core/common/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/di/NativeDispatchersComponent.kt +++ b/core/common/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/di/NativeDispatchersComponent.kt @@ -16,6 +16,9 @@ package com.google.samples.apps.nowinandroid.core.di +import com.google.samples.apps.nowinandroid.core.di.NiaDispatchers.DEFAULT +import com.google.samples.apps.nowinandroid.core.di.NiaDispatchers.IO +import com.google.samples.apps.nowinandroid.core.di.NiaDispatchers.MAIN import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.IO @@ -25,9 +28,18 @@ import me.tatarka.inject.annotations.Provides @Component abstract class NativeDispatchersComponent : DispatchersComponent() { @Provides - override fun providesIODispatcher(): @IoDispatcher CoroutineDispatcher = Dispatchers.IO + override fun providesIODispatcher(): + @Dispatcher(IO) + CoroutineDispatcher = Dispatchers.IO @Provides - override fun providesDefaultDispatcher(): @DefaultDispatcher CoroutineDispatcher = + override fun providesDefaultDispatcher(): + @Dispatcher(DEFAULT) + CoroutineDispatcher = Dispatchers.Default + + @Provides + override fun providesMainDispatcher(): + @Dispatcher(MAIN) + CoroutineDispatcher = Dispatchers.Main } diff --git a/core/data/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/data/di/AndroidPlatformDependentDataModule.kt b/core/data/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/data/di/AndroidPlatformDependentDataModule.kt index b42830ae0..d5f89defb 100644 --- a/core/data/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/data/di/AndroidPlatformDependentDataModule.kt +++ b/core/data/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/data/di/AndroidPlatformDependentDataModule.kt @@ -23,8 +23,9 @@ import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneBroadcastMoni import com.google.samples.apps.nowinandroid.core.data.util.TimeZoneMonitor import com.google.samples.apps.nowinandroid.core.di.AndroidApplicationComponent import com.google.samples.apps.nowinandroid.core.di.CoroutineScopeComponent +import com.google.samples.apps.nowinandroid.core.di.Dispatcher import com.google.samples.apps.nowinandroid.core.di.DispatchersComponent -import com.google.samples.apps.nowinandroid.core.di.IoDispatcher +import com.google.samples.apps.nowinandroid.core.di.NiaDispatchers.IO import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import me.tatarka.inject.annotations.Component @@ -38,7 +39,8 @@ abstract class AndroidPlatformDependentDataModule( ) : PlatformDependentDataModule() { abstract val application: Application - @IoDispatcher abstract val ioDispatcher: CoroutineDispatcher + @Dispatcher(IO) + abstract val ioDispatcher: CoroutineDispatcher abstract val coroutineScope: CoroutineScope @Provides 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 921b63dba..77b36d9b7 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 @@ -23,7 +23,8 @@ import com.google.samples.apps.nowinandroid.core.database.dao.TopicFtsDao import com.google.samples.apps.nowinandroid.core.database.model.PopulatedNewsResource import com.google.samples.apps.nowinandroid.core.database.model.asExternalModel import com.google.samples.apps.nowinandroid.core.database.model.asFtsEntity -import com.google.samples.apps.nowinandroid.core.di.IoDispatcher +import com.google.samples.apps.nowinandroid.core.di.Dispatcher +import com.google.samples.apps.nowinandroid.core.di.NiaDispatchers.IO import com.google.samples.apps.nowinandroid.core.model.data.SearchResult import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -43,7 +44,7 @@ class DefaultSearchContentsRepository( private val newsResourceFtsDao: NewsResourceFtsDao, private val topicDao: TopicDao, private val topicFtsDao: TopicFtsDao, - @IoDispatcher private val ioDispatcher: CoroutineDispatcher, + @Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher, ) : SearchContentsRepository { override suspend fun populateFtsData() { diff --git a/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/di/DatabaseModule.kt b/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/di/DatabaseModule.kt index d202e5229..37d332fda 100644 --- a/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/di/DatabaseModule.kt +++ b/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/di/DatabaseModule.kt @@ -23,15 +23,17 @@ import com.google.samples.apps.nowinandroid.core.database.dao.NewsResourceFtsDao import com.google.samples.apps.nowinandroid.core.database.dao.RecentSearchQueryDao import com.google.samples.apps.nowinandroid.core.database.dao.TopicDao import com.google.samples.apps.nowinandroid.core.database.dao.TopicFtsDao +import com.google.samples.apps.nowinandroid.core.di.Dispatcher import com.google.samples.apps.nowinandroid.core.di.DispatchersComponent -import com.google.samples.apps.nowinandroid.core.di.IoDispatcher +import com.google.samples.apps.nowinandroid.core.di.NiaDispatchers.IO import kotlinx.coroutines.CoroutineDispatcher import me.tatarka.inject.annotations.Component import me.tatarka.inject.annotations.Provides @Component abstract class DatabaseModule(@Component val dispatchersComponent: DispatchersComponent) { - @IoDispatcher abstract val dispatcher: CoroutineDispatcher + @Dispatcher(IO) + abstract val dispatcher: CoroutineDispatcher @Provides fun providesNiaDatabase(driver: SqlDriver): NiaDatabase = NiaDatabase(driver) 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 d7248081c..62f9a85e0 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 @@ -15,7 +15,8 @@ */ package com.google.samples.apps.nowinandroid.core.datastore -import com.google.samples.apps.nowinandroid.core.di.IoDispatcher +import com.google.samples.apps.nowinandroid.core.di.Dispatcher +import com.google.samples.apps.nowinandroid.core.di.NiaDispatchers.IO import com.google.samples.apps.nowinandroid.core.model.data.DarkThemeConfig import com.google.samples.apps.nowinandroid.core.model.data.ThemeBrand import com.google.samples.apps.nowinandroid.core.model.data.UserData @@ -38,7 +39,7 @@ private const val USER_DATA_KEY = "userData" @Inject class NiaPreferencesDataSource( private val settings: Settings, - @IoDispatcher private val dispatcher: CoroutineDispatcher, + @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/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 379ebaf16..96083fd2c 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 @@ -16,7 +16,8 @@ package com.google.samples.apps.nowinandroid.core.network.demo -import com.google.samples.apps.nowinandroid.core.di.IoDispatcher +import com.google.samples.apps.nowinandroid.core.di.Dispatcher +import com.google.samples.apps.nowinandroid.core.di.NiaDispatchers.IO import com.google.samples.apps.nowinandroid.core.network.NiaNetworkDataSource import com.google.samples.apps.nowinandroid.core.network.assets.NEWS_DATA import com.google.samples.apps.nowinandroid.core.network.assets.TOPICS_DATA @@ -32,7 +33,7 @@ import me.tatarka.inject.annotations.Inject * [NiaNetworkDataSource] implementation that provides static news resources to aid development */ class DemoNiaNetworkDataSource @Inject constructor( - @IoDispatcher private val ioDispatcher: CoroutineDispatcher, + @Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher, private val networkJson: Json, ) : NiaNetworkDataSource { diff --git a/feature/bookmarks/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt b/feature/bookmarks/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt index 9b8010625..fbff1abbf 100644 --- a/feature/bookmarks/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt +++ b/feature/bookmarks/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksViewModelTest.kt @@ -36,6 +36,7 @@ import kotlin.test.assertIs * To learn more about how this test handles Flows created with stateIn, see * https://developer.android.com/kotlin/flow/test#statein */ +@OptIn(ExperimentalCoroutinesApi::class) class BookmarksViewModelTest { private val userDataRepository = TestUserDataRepository() private val newsRepository = TestNewsRepository() @@ -71,7 +72,6 @@ class BookmarksViewModelTest { collectJob.cancel() } - @OptIn(ExperimentalCoroutinesApi::class) @Test fun oneBookmark_whenRemoving_removesFromFeed() = runTest { val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.feedUiState.collect() }