Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@
- `com.streamplayer.kmp-library` — base KMP module setup (multiplatform, serialization, parcelize, dokka, detekt)
- `com.streamplayer.dokka` — documentation generation
- `com.streamplayer.detekt` — static analysis
- `com.streamplayer.koin-annotations-setup` — Koin annotation processing
- `com.streamplayer.koin-annotations-setup` — Koin Annotations artifacts (the Koin Compiler Plugin is applied by `com.streamplayer.kmp-library`)
- `popcorngp-setup-plugin` — Popcorn Guinea Pig test setup

### Key Dependencies

- Compose Multiplatform 1.10.0
- Koin 4.2.0 / Koin Annotations 2.3.1
- Koin 4.2.2 / Koin Compiler Plugin 1.2.3 (Koin Annotations, no KSP)
- Ktor 3.0.1 / OkHttp 4.12.0
- Room 2.7.0-alpha13
- Coil 3.1.0
Expand Down
1 change: 1 addition & 0 deletions androidApp/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
id("com.android.application")
alias(libs.plugins.jetbrains.compose)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.koin.compiler)
alias(libs.plugins.google.services)
alias(libs.plugins.firebase.crashlytics)
}
Expand Down
1 change: 1 addition & 0 deletions build-logic/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ dependencies {
implementation(libs.detekt.gradle.plugin)
implementation(libs.serialization)
implementation(libs.com.google.devtools.ksp.gradle.plugin)
implementation(libs.koin.compiler.gradle.plugin)
implementation(libs.popcorn.guineapig)
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import extensions.iosTarget
import org.gradle.accessors.dm.LibrariesForLibs
import org.gradle.kotlin.dsl.the
import org.koin.compiler.plugin.KoinGradleExtension

val libs = the<LibrariesForLibs>()

Expand All @@ -13,6 +14,11 @@ plugins {
id("kotlin-parcelize")
id("com.streamplayer.dokka")
id("com.streamplayer.detekt")
id("io.insert-koin.compiler.plugin")
}

configure<KoinGradleExtension> {
compileSafety = true
}

kotlin {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import org.gradle.accessors.dm.LibrariesForLibs
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.gradle.kotlin.dsl.the

val libs = the<LibrariesForLibs>()

plugins {
id("org.jetbrains.kotlin.multiplatform")
id("com.google.devtools.ksp")
}

kotlin {
Expand All @@ -15,35 +14,4 @@ kotlin {
api(libs.koin.annotations)
}
}

// KSP Common sourceSet
sourceSets.named("commonMain").configure {
kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin")
}
}

// KSP Tasks
dependencies {
add("kspCommonMainMetadata", libs.koin.ksp.compiler)
}


// WORKAROUND: ADD this dependsOn("kspCommonMainKotlinMetadata") instead of above dependencies
tasks.withType<KotlinCompile>().configureEach {
if (name != "kspCommonMainKotlinMetadata") {
dependsOn("kspCommonMainKotlinMetadata")
}
}

afterEvaluate {
tasks.filter {
it.name.contains("SourcesJar", true)
}.forEach {
println("SourceJarTask====>${it.name}")
it.dependsOn("kspCommonMainKotlinMetadata")
}
}

ksp {
arg("KOIN_CONFIG_CHECK", "true")
}
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ plugins {
alias(libs.plugins.jetbrains.compose) apply false
alias(libs.plugins.compose.compiler) apply false
alias(libs.plugins.ksp) apply false
alias(libs.plugins.koin.compiler) apply false
alias(libs.plugins.dokka) apply false
alias(libs.plugins.buildkonfig.plugin) apply false
id("popcorngp-setup-plugin")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,36 @@ package com.codandotv.streamplayerapp.composeApp.presentation.di

import com.codandotv.streamplayerapp.core.background.work.di.SyncModule
import com.codandotv.streamplayerapp.core.local.storage.di.LocalStorageModule
import com.codandotv.streamplayerapp.core.networking.di.NetworkModule
import com.codandotv.streamplayerapp.core.session.di.coreSessionModule
import com.codandotv.streamplayerapp.core.shared.qualifier.QualifierDispatcherIO
import com.codandotv.streamplayerapp.feature.liststreams.list.di.ListStreamModule
import com.codandotv.streamplayerapp.feature.news.di.NewsScreenModule
import com.codandotv.streamplayerapp.feature.profile.di.ProfilePickerStreamModule
import com.codandotv.streamplayerapp.feature.search.di.SearchModule
import io.kotzilla.generated.monitoring
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import org.koin.core.KoinApplication
import org.koin.core.context.startKoin
import org.koin.core.lazyModules
import org.koin.dsl.module
import org.koin.ksp.generated.module
import org.koin.plugin.module.dsl.startKoin

fun streamPlayerApplication(platformBlock: KoinApplication.() -> Unit): KoinApplication {
return startKoin {
return startKoin<KoinApp> {
platformBlock()
lazyModules(PermissionsModule.module)

// Annotated modules (NetworkModule, SearchModule, NewsScreenModule,
// ProfilePickerStreamModule) are discovered from @Configuration by the
// Koin Compiler Plugin — only the DSL modules are listed here.
modules(
PermissionsModule.module,
module {
single(QualifierDispatcherIO) {
Dispatchers.IO
}
},
coreSessionModule,
NetworkModule().module,
LocalStorageModule.module,
SyncModule.module,

// region feature_modules
ListStreamModule.module,
SearchModule().module,
NewsScreenModule().module,
ProfilePickerStreamModule().module
ListStreamModule.module
// endregion
)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.codandotv.streamplayerapp.composeApp.presentation.di

import org.koin.core.annotation.KoinApplication

/**
* Koin application entry point, scanned by the Koin Compiler Plugin.
*
* Every `@Module` tagged with `@Configuration` on the compile classpath of this
* module is discovered and loaded by `startKoin<KoinApp>()`.
*/
@KoinApplication
object KoinApp
1 change: 0 additions & 1 deletion core-background-work/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

plugins {
id("com.streamplayer.kmp-library")
id("com.google.devtools.ksp")
}

kotlin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,25 @@ package com.codandotv.streamplayerapp.core.networking.di
import com.codandotv.streamplayerapp.core.networking.HttpClientBuilder
import core.networking.BuildKonfig
import io.ktor.client.HttpClient
import org.koin.core.annotation.ComponentScan
import org.koin.core.annotation.Configuration
import org.koin.core.annotation.Module
import org.koin.core.annotation.Qualifier
import org.koin.core.annotation.Single
import org.koin.core.annotation.Singleton

@Module
@Configuration
@ComponentScan("com.codandotv.streamplayerapp.core.networking.di")
class NetworkModule {

@Single
@Singleton
fun provideHttpClient(): HttpClient {
return HttpClientBuilder.build(
baseUrl = BuildKonfig.HOST,
)
}

@Single
@Singleton
@Qualifier(QualifierProfileHttpClient::class)
fun provideProfileHttpClient(): HttpClient {
return HttpClientBuilder.build(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
import com.codandotv.streamplayerapp.core.permission.PermissionFactory
import com.codandotv.streamplayerapp.core.permission.PermissionsManager
import com.codandotv.streamplayerapp.core.permission.PermissionsManagerImpl
import org.koin.dsl.lazyModule
import org.koin.dsl.module

object PermissionsModule {
val module = lazyModule {
val module = module {
single<PermissionsManager> {
PermissionsManagerImpl(
controller = PermissionFactory()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.codandotv.streamplayerapp.feature.news.di

import org.koin.core.annotation.ComponentScan
import org.koin.core.annotation.Configuration
import org.koin.core.annotation.Module

@Module
@Configuration
@ComponentScan("com.codandotv.streamplayerapp.feature.news")
class NewsScreenModule
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import org.koin.android.annotation.KoinViewModel
import org.koin.core.annotation.Provided
import org.koin.core.annotation.KoinViewModel

data class NewsScreenUiState(
val showPermissionDialog: Boolean = false,
Expand All @@ -27,7 +26,7 @@ sealed class NewsScreenActionTakeImage {

@KoinViewModel
class NewsScreenViewModel(
@Provided val permissionsManager: PermissionsManager
val permissionsManager: PermissionsManager
) : ViewModel() {
private val _actionTakeImage = MutableSharedFlow<NewsScreenActionTakeImage>()
val actionTakeImage: SharedFlow<NewsScreenActionTakeImage> = _actionTakeImage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ import com.codandotv.streamplayerapp.feature.profile.data.model.ProfilesResponse
import io.ktor.client.HttpClient
import io.ktor.client.request.url
import org.koin.core.annotation.Factory
import org.koin.core.annotation.Provided

interface ProfilePickerStreamService {
suspend fun getProfiles(): NetworkResponse<ProfilesResponse>
}

@Factory
class ProfilePickerStreamServiceImpl(
@Provided private val client: HttpClient
private val client: HttpClient
) : ProfilePickerStreamService {
override suspend fun getProfiles(): NetworkResponse<ProfilesResponse> =
client.safeRequest {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.codandotv.streamplayerapp.feature.profile.di

import org.koin.core.annotation.ComponentScan
import org.koin.core.annotation.Configuration
import org.koin.core.annotation.Module

@Module
@Configuration
@ComponentScan("com.codandotv.streamplayerapp.feature.profile")
class ProfilePickerStreamModule
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import org.koin.android.annotation.KoinViewModel
import org.koin.core.annotation.Provided
import org.koin.core.annotation.KoinViewModel

@KoinViewModel
class ProfilePickerStreamViewModel(
@Provided private val sessionManager: SessionManager,
private val sessionManager: SessionManager,
private val useCase: ProfilePickerStreamUseCase,
) : ViewModel() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ import com.codandotv.streamplayerapp.feature.search.data.model.ListSearchStreamR
import io.ktor.client.HttpClient
import io.ktor.client.request.url
import org.koin.core.annotation.Factory
import org.koin.core.annotation.Provided

interface MostPopularMoviesService {
suspend fun getPopular(): NetworkResponse<ListSearchStreamResponse>
}

@Factory(binds = [MostPopularMoviesService::class])
class MostPopularMoviesServiceImpl(
@Provided private val client: HttpClient
private val client: HttpClient
) : MostPopularMoviesService {
override suspend fun getPopular(): NetworkResponse<ListSearchStreamResponse> =
client.safeRequest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@ import io.ktor.client.HttpClient
import io.ktor.client.request.parameter
import io.ktor.client.request.url
import org.koin.core.annotation.Factory
import org.koin.core.annotation.Provided

interface SearchStreamService {
suspend fun getSearch(query: String): NetworkResponse<ListSearchStreamResponse>
}

@Factory(binds = [SearchStreamService::class])
class SearchStreamServiceImpl(
@Provided private val client: HttpClient
private val client: HttpClient
) : SearchStreamService {
override suspend fun getSearch(query: String): NetworkResponse<ListSearchStreamResponse> =
client.safeRequest {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.codandotv.streamplayerapp.feature.search.di

import org.koin.core.annotation.ComponentScan
import org.koin.core.annotation.Configuration
import org.koin.core.annotation.Module

@Module
@Configuration
@ComponentScan("com.codandotv.streamplayerapp.feature.search")
class SearchModule
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,13 @@ import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import org.koin.android.annotation.KoinViewModel
import org.koin.core.annotation.Provided
import org.koin.core.annotation.KoinViewModel

@KoinViewModel
class SearchViewModel(
private val searchUseCase: SearchUseCase,
private val mostPopularMoviesUseCase: MostPopularMoviesUseCase,
@Provided private val sessionManager: SessionManager
private val sessionManager: SessionManager
) : ViewModel() {

private var tryAgain: () -> Unit = {}
Expand Down
18 changes: 10 additions & 8 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[versions]
kotlin = "2.3.20"
android_gradle_plugin = "9.1.0"
koin = "4.2.0"
koin-annotations = "2.3.1"
koin = "4.2.2"
koin-compiler = "1.2.3"
ksp = "2.3.5"
kotzilla = "2.1.3"
lifecycle-viewmodel-compose-version = "2.9.6"
Expand Down Expand Up @@ -87,15 +87,16 @@ androidx-camera-core = { module = "androidx.camera:camera-core", version.ref = "
androidx-camera-lifecycle = { module = "androidx.camera:camera-lifecycle", version.ref = "cameraCore" }
androidx-camera-view = { module = "androidx.camera:camera-view", version.ref = "cameraCore" }

# Koin
koin_test = { group = "io.insert-koin", name = "koin-test-junit4", version.ref = "koin" }
koin_android = { group = "io.insert-koin", name = "koin-android", version.ref = "koin" }
koin_core = { group = "io.insert-koin", name = "koin-core", version.ref = "koin" }
koin-annotations = { module = "io.insert-koin:koin-annotations", version.ref = "koin-annotations" }
koin-ksp-compiler = { module = "io.insert-koin:koin-ksp-compiler", version.ref = "koin-annotations" }
# Koin — all artifacts share the `koin` version key (no BOM: platform(Any) is
# DeprecationLevel.ERROR in the Kotlin DSL of the build-logic precompiled scripts)
koin_test = { module = "io.insert-koin:koin-test-junit4", version.ref = "koin" }
koin_android = { module = "io.insert-koin:koin-android", version.ref = "koin" }
koin_core = { module = "io.insert-koin:koin-core", version.ref = "koin" }
koin-annotations = { module = "io.insert-koin:koin-annotations", version.ref = "koin" }
koin_compose = { module = "io.insert-koin:koin-compose", version.ref = "koin" }
koin_compose_viewmodel = { module = "io.insert-koin:koin-compose-viewmodel", version.ref = "koin" }
koin_core_coroutines = { module = "io.insert-koin:koin-core-coroutines", version.ref = "koin" }
koin-compiler-gradle-plugin = { module = "io.insert-koin:koin-compiler-gradle-plugin", version.ref = "koin-compiler" }

#Networking
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }
Expand Down Expand Up @@ -183,6 +184,7 @@ compose_compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "
room = { id = "androidx.room", version.ref = "room" }

ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
koin-compiler = { id = "io.insert-koin.compiler.plugin", version.ref = "koin-compiler" }
dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" }

buildkonfig_plugin = { id = "com.codingfeline.buildkonfig", version.ref = "buildkonfig" }
Expand Down
Loading