From 48d9600a41b497c169107a21e9e2d7c2d989d6e2 Mon Sep 17 00:00:00 2001 From: Gabriel Bronzatti Moro Date: Sun, 2 Feb 2025 19:31:13 -0300 Subject: [PATCH 01/14] Solve local storage module --- core-local-storage/build.gradle.kts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core-local-storage/build.gradle.kts b/core-local-storage/build.gradle.kts index e62f9b43..69743322 100644 --- a/core-local-storage/build.gradle.kts +++ b/core-local-storage/build.gradle.kts @@ -9,8 +9,7 @@ kotlin { commonMain.dependencies { implementation(libs.room.bundled) implementation(libs.room.runtime) - implementation(libs.bundles.kotlin) - implementation(libs.bundles.koin) + implementation(libs.koin.core) } } From 9233012865bfe1f07ebe3536d96a207943eadca9 Mon Sep 17 00:00:00 2001 From: Gabriel Bronzatti Moro Date: Sun, 2 Feb 2025 23:12:59 -0300 Subject: [PATCH 02/14] Migrate core-networking to androidMain --- core-networking/build.gradle.kts | 17 +++- .../HttpClientEngineProvider.android.kt | 7 ++ .../HttpClientEngineProvider.kt | 7 ++ .../core_networking/di/NetworkModule.kt | 79 +++++++------------ .../handleError/HttpClientConfigExtensions.kt | 40 ---------- 5 files changed, 56 insertions(+), 94 deletions(-) create mode 100644 core-networking/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProvider.android.kt create mode 100644 core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProvider.kt diff --git a/core-networking/build.gradle.kts b/core-networking/build.gradle.kts index e8ebc126..9f86234e 100644 --- a/core-networking/build.gradle.kts +++ b/core-networking/build.gradle.kts @@ -26,10 +26,21 @@ android { kotlin { sourceSets { commonMain.dependencies { - implementation(libs.bundles.kotlin) - implementation(libs.bundles.networking) - implementation(libs.bundles.koin) + implementation(libs.kotlin.stdlib) + implementation(libs.koin.core) + implementation(libs.ktor.client.core) + implementation(libs.ktor.client.content.serialization.json) + implementation(libs.ktor.client.content.negotiation) + implementation(libs.ktor.client.logger) + implementation(libs.ktor.client.auth) implementation(compose.components.resources) + implementation(compose.runtime) + } + + androidMain.dependencies { + implementation(libs.okhttp) + implementation(libs.interceptor) + implementation(libs.ktor.client.okhttp) } } } \ No newline at end of file diff --git a/core-networking/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProvider.android.kt b/core-networking/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProvider.android.kt new file mode 100644 index 00000000..04598d01 --- /dev/null +++ b/core-networking/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProvider.android.kt @@ -0,0 +1,7 @@ +package com.codandotv.streamplayerapp.core_networking + +import io.ktor.client.engine.HttpClientEngine +import io.ktor.client.engine.okhttp.OkHttpConfig +import io.ktor.client.engine.okhttp.OkHttpEngine + +actual fun httpClientEngine() : HttpClientEngine = OkHttpEngine(OkHttpConfig()) \ No newline at end of file diff --git a/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProvider.kt b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProvider.kt new file mode 100644 index 00000000..a8f99a4a --- /dev/null +++ b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProvider.kt @@ -0,0 +1,7 @@ +@file:Suppress("EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE") + +package com.codandotv.streamplayerapp.core_networking + +import io.ktor.client.engine.HttpClientEngine + +expect fun httpClientEngine(): HttpClientEngine \ No newline at end of file diff --git a/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/di/NetworkModule.kt b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/di/NetworkModule.kt index ddceb396..8325ce22 100644 --- a/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/di/NetworkModule.kt +++ b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/di/NetworkModule.kt @@ -3,13 +3,8 @@ package com.codandotv.streamplayerapp.core_networking.di import android.util.Log import com.codandotv.streamplayerapp.core.networking.BuildConfig import com.codandotv.streamplayerapp.core_networking.di.Network.TIMEOUT -import com.codandotv.streamplayerapp.core_networking.handleError.validator -import com.squareup.moshi.Moshi +import com.codandotv.streamplayerapp.core_networking.httpClientEngine import io.ktor.client.HttpClient -import io.ktor.client.HttpClientConfig -import io.ktor.client.engine.okhttp.OkHttp -import io.ktor.client.engine.okhttp.OkHttpConfig -import io.ktor.client.plugins.HttpResponseValidator import io.ktor.client.plugins.HttpTimeout import io.ktor.client.plugins.auth.Auth import io.ktor.client.plugins.auth.providers.BearerTokens @@ -23,9 +18,7 @@ import io.ktor.client.request.accept import io.ktor.http.ContentType import io.ktor.http.contentType import io.ktor.serialization.kotlinx.json.json -import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.Json -import okhttp3.Interceptor import org.koin.dsl.module object NetworkModule { @@ -35,69 +28,53 @@ object NetworkModule { single { provideKtorHttpClient( - moshi = get(), baseUrl = get(QualifierHost), ) } single(QualifierProfileHttpClient) { provideKtorHttpClient( - moshi = get(), baseUrl = get(QualifierProfile), ) } - - single { Moshi.Builder().build() } } private fun provideKtorHttpClient( - moshi: Moshi, baseUrl: String, ): HttpClient { - return HttpClient(OkHttp) { - installPlugins(moshi, baseUrl) - } - } - - private fun HttpClientConfig.installPlugins( - moshi: Moshi, - baseUrl: String, - ) { - expectSuccess = false - - install(ContentNegotiation) { - json(Json { - explicitNulls = false - ignoreUnknownKeys = true - }) - } + return HttpClient(engine = httpClientEngine()) { + expectSuccess = false - install(HttpTimeout) { - socketTimeoutMillis = TIMEOUT - requestTimeoutMillis = TIMEOUT - connectTimeoutMillis = TIMEOUT - } + install(ContentNegotiation) { + json(Json { + explicitNulls = false + ignoreUnknownKeys = true + }) + } - defaultRequest { - url(baseUrl) - contentType(ContentType.Application.Json) - accept(ContentType.Application.Json) - } + install(HttpTimeout) { + socketTimeoutMillis = TIMEOUT + requestTimeoutMillis = TIMEOUT + connectTimeoutMillis = TIMEOUT + } - validator(moshi) + defaultRequest { + url(baseUrl) + contentType(ContentType.Application.Json) + accept(ContentType.Application.Json) + } - install(Auth) { - bearer { - loadTokens { - BearerTokens( - accessToken = BuildConfig.API_BEARER_AUTH, - refreshToken = "" - ) + install(Auth) { + bearer { + loadTokens { + BearerTokens( + accessToken = BuildConfig.API_BEARER_AUTH, + refreshToken = "" + ) + } } } - } - if (BuildConfig.DEBUG) { install(Logging) { level = LogLevel.ALL logger = object : Logger { @@ -110,6 +87,6 @@ object NetworkModule { } } -internal object Network{ +internal object Network { const val TIMEOUT = 10000L } \ No newline at end of file diff --git a/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/handleError/HttpClientConfigExtensions.kt b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/handleError/HttpClientConfigExtensions.kt index ec896a04..5ccadb2c 100644 --- a/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/handleError/HttpClientConfigExtensions.kt +++ b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/handleError/HttpClientConfigExtensions.kt @@ -1,54 +1,14 @@ package com.codandotv.streamplayerapp.core_networking.handleError -import android.util.Log -import com.squareup.moshi.Moshi import io.ktor.client.HttpClient -import io.ktor.client.HttpClientConfig import io.ktor.client.call.body -import io.ktor.client.engine.okhttp.OkHttpConfig import io.ktor.client.plugins.ClientRequestException -import io.ktor.client.plugins.HttpResponseValidator import io.ktor.client.request.HttpRequestBuilder import io.ktor.client.request.request import io.ktor.client.statement.bodyAsText import io.ktor.utils.io.errors.IOException import kotlinx.serialization.SerializationException -internal fun HttpClientConfig.validator( - moshi: Moshi -) { - HttpResponseValidator { - validateResponse { response -> - when (response.status.value) { - in 200..299 -> Unit - in 400..499 -> { - val errorBody = response.bodyAsText() - val error = try { - moshi.adapter(NetworkResponse.Error::class.java).fromJson(errorBody) - } catch (e: Exception) { - throw Failure.UnparsableResponseException(throwable = e) - } - throw Failure.ClientException(throwable = error?.exception) - } - - in 500..599 -> throw Failure.ServerError(response.status.value) - else -> throw Failure.UnknownError(response.status.value) - } - } - - handleResponseExceptionWithRequest { exception, _ -> - Log.d("HttpClientError",exception.stackTraceToString()) - - when (exception) { - is IOException -> throw Failure.NetworkError(throwable = exception) - else -> throw Failure.GenericError( - msg = exception.message ?: "Unknown error" - ) - } - } - } -} - suspend inline fun HttpClient.safeRequest( block: HttpRequestBuilder.() -> Unit, ): NetworkResponse = From 89717f76fc172204601696a9dbe031a474f0d3fd Mon Sep 17 00:00:00 2001 From: Gabriel Bronzatti Moro Date: Sun, 2 Feb 2025 23:26:02 -0300 Subject: [PATCH 03/14] Migrate core-networking to androidMain --- build-logic/src/main/java/Config.kt | 10 +++----- build.gradle.kts | 1 + core-networking/build.gradle.kts | 24 +++++++------------ .../core_networking/di/NetworkModule.kt | 8 +++---- gradle/libs.versions.toml | 4 +++- 5 files changed, 20 insertions(+), 27 deletions(-) diff --git a/build-logic/src/main/java/Config.kt b/build-logic/src/main/java/Config.kt index 4c699b1a..e21583a3 100644 --- a/build-logic/src/main/java/Config.kt +++ b/build-logic/src/main/java/Config.kt @@ -8,17 +8,13 @@ object Config { const val testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" object BuildField { - const val host_debug = "\"https://api.themoviedb.org/3/\"" - const val host_release = "\"https://api.themoviedb.org/3/\"" - const val api_profile_debug = "\"https://demo3364084.mockable.io/\"" - const val api_profile_release = "\"https://demo3364084.mockable.io/\"" + const val host = "https://api.themoviedb.org/3/" + const val api_profile = "https://demo3364084.mockable.io/" private const val tmdb_token_name_debug = "TMDB_BEARER_TOKEN_DEBUG" - private const val tmdb_token_name_release = "TMDB_BEARER_TOKEN_RELEASE" private const val bearear_without_environment = "eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJiNDg2NWM4YTAzNzhmM2I4NjI0OWU1ZjNiYWFiMjU2NyIsInN1YiI6IjY0Mjk4YTg5YTNlNGJhMWM0NDgzM2U4OCIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.9cIxv29vkaZ2yW88DIFRUFK_nXbK2b6KS8t96kA8WAE" - val api_bearer_debug = "\"${System.getenv(tmdb_token_name_debug) ?: bearear_without_environment}\"" - val api_bearer_release = "\"${System.getenv(tmdb_token_name_release) ?: bearear_without_environment}\"" + val api_bearer = System.getenv(tmdb_token_name_debug) ?: bearear_without_environment } } \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index a6c82513..4e1f6f7b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,6 +12,7 @@ plugins { alias(libs.plugins.ksp) apply false alias(libs.plugins.dokka) apply false alias(libs.plugins.kover) apply false + alias(libs.plugins.buildkonfig.plugin) apply false } tasks.register("clean", Delete::class) { diff --git a/core-networking/build.gradle.kts b/core-networking/build.gradle.kts index 9f86234e..f30e603a 100644 --- a/core-networking/build.gradle.kts +++ b/core-networking/build.gradle.kts @@ -1,25 +1,19 @@ +import com.codingfeline.buildkonfig.compiler.FieldSpec + plugins { id("com.streamplayer.kmp-library") alias(libs.plugins.jetbrains.compose) alias(libs.plugins.compose.compiler) + alias(libs.plugins.buildkonfig.plugin) } -android { - buildFeatures { - buildConfig = true - } - buildTypes { - debug { - buildConfigField("String", "HOST", Config.BuildField.host_debug) - buildConfigField("String", "API_BEARER_AUTH", Config.BuildField.api_bearer_debug) - buildConfigField("String", "PROFILE", Config.BuildField.api_profile_debug) +buildkonfig { + packageName = "core.networking" - } - getByName("release") { - buildConfigField("String", "HOST", Config.BuildField.host_release) - buildConfigField("String", "API_BEARER_AUTH", Config.BuildField.api_bearer_release) - buildConfigField("String", "PROFILE", Config.BuildField.api_profile_release) - } + defaultConfigs { + buildConfigField(FieldSpec.Type.STRING, "HOST", Config.BuildField.host) + buildConfigField(FieldSpec.Type.STRING, "API_BEARER_AUTH", Config.BuildField.api_bearer) + buildConfigField(FieldSpec.Type.STRING, "PROFILE", Config.BuildField.api_profile) } } diff --git a/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/di/NetworkModule.kt b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/di/NetworkModule.kt index 8325ce22..aca7f32e 100644 --- a/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/di/NetworkModule.kt +++ b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/di/NetworkModule.kt @@ -1,9 +1,9 @@ package com.codandotv.streamplayerapp.core_networking.di import android.util.Log -import com.codandotv.streamplayerapp.core.networking.BuildConfig import com.codandotv.streamplayerapp.core_networking.di.Network.TIMEOUT import com.codandotv.streamplayerapp.core_networking.httpClientEngine +import core.networking.BuildKonfig import io.ktor.client.HttpClient import io.ktor.client.plugins.HttpTimeout import io.ktor.client.plugins.auth.Auth @@ -23,8 +23,8 @@ import org.koin.dsl.module object NetworkModule { val module = module { - single(QualifierHost) { BuildConfig.HOST } - single(QualifierProfile) { BuildConfig.PROFILE } + single(QualifierHost) { BuildKonfig.HOST } + single(QualifierProfile) { BuildKonfig.PROFILE } single { provideKtorHttpClient( @@ -68,7 +68,7 @@ object NetworkModule { bearer { loadTokens { BearerTokens( - accessToken = BuildConfig.API_BEARER_AUTH, + accessToken = BuildKonfig.API_BEARER_AUTH, refreshToken = "" ) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6eaaea92..03cb4d4f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,6 +11,7 @@ detekt = "1.23.6" compose_plugin_multiplataform = "1.7.1" navigation-compose-version = "2.7.0-alpha07" paging-compose = "3.3.5" +buildkonfig = "0.15.2" #Test test_junit = "4.13.2" @@ -138,4 +139,5 @@ ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } -detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } \ No newline at end of file +detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } +buildkonfig_plugin = { id = "com.codingfeline.buildkonfig", version.ref = "buildkonfig" } From 881624df862e24099bd14f62336f9ee9816eb971 Mon Sep 17 00:00:00 2001 From: Gabriel Bronzatti Moro Date: Sun, 2 Feb 2025 23:28:41 -0300 Subject: [PATCH 04/14] Migrate core-local-storage to androidMain --- core-local-storage/build.gradle.kts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/core-local-storage/build.gradle.kts b/core-local-storage/build.gradle.kts index 69743322..56092c54 100644 --- a/core-local-storage/build.gradle.kts +++ b/core-local-storage/build.gradle.kts @@ -12,24 +12,10 @@ kotlin { implementation(libs.koin.core) } } - - listOf( - iosX64(), - iosArm64(), - iosSimulatorArm64() - ).forEach { iosTarget -> - iosTarget.binaries.framework { - baseName = "composeApp" - isStatic = true - } - } } dependencies { add("kspAndroid", libs.room.compiler) - add("kspIosSimulatorArm64", libs.room.compiler) - add("kspIosX64", libs.room.compiler) - add("kspIosArm64", libs.room.compiler) } configurations.implementation{ From 331540d69eca01c3cfefe51e4369c2e7c0346e19 Mon Sep 17 00:00:00 2001 From: Gabriel Bronzatti Moro Date: Mon, 3 Feb 2025 07:42:21 -0300 Subject: [PATCH 05/14] Remove unnecessary annotations + add ktor dependencies to the client modules --- feature-detail/build.gradle.kts | 4 +++- feature-list-streams/build.gradle.kts | 4 +++- feature-profile/build.gradle.kts | 5 +++-- .../profile/data/ProfilePickerStreamRepository.kt | 2 -- .../profile/domain/ProfilePickerStreamUseCase.kt | 2 -- .../screens/ProfilePickerStreamViewModel.kt | 2 -- feature-search/build.gradle.kts | 4 +++- .../data/model/ListSearchStreamResponse.kt | 12 ++++++------ gradle/libs.versions.toml | 5 ----- 9 files changed, 18 insertions(+), 22 deletions(-) diff --git a/feature-detail/build.gradle.kts b/feature-detail/build.gradle.kts index 2c2392d8..0da20c8d 100644 --- a/feature-detail/build.gradle.kts +++ b/feature-detail/build.gradle.kts @@ -21,10 +21,12 @@ kotlin { implementation(compose.preview) implementation(libs.navigation.compose) implementation(libs.bundles.koin) - implementation(libs.bundles.networking) implementation(libs.coil) implementation(libs.bundles.androidSupport) implementation(compose.components.resources) + + implementation(libs.ktor.client.content.serialization.json) + implementation(libs.ktor.client.content.negotiation) } commonTest.dependencies { implementation(libs.bundles.test) diff --git a/feature-list-streams/build.gradle.kts b/feature-list-streams/build.gradle.kts index b5eb796b..e8f628d6 100644 --- a/feature-list-streams/build.gradle.kts +++ b/feature-list-streams/build.gradle.kts @@ -22,9 +22,11 @@ kotlin { implementation(compose.ui) implementation(compose.preview) implementation(libs.navigation.compose) - implementation(libs.bundles.networking) implementation(libs.coil) implementation(libs.bundles.androidSupport) + + implementation(libs.ktor.client.content.serialization.json) + implementation(libs.ktor.client.content.negotiation) } } } \ No newline at end of file diff --git a/feature-profile/build.gradle.kts b/feature-profile/build.gradle.kts index 37880dfa..1dd0accc 100644 --- a/feature-profile/build.gradle.kts +++ b/feature-profile/build.gradle.kts @@ -19,11 +19,12 @@ kotlin { implementation(compose.components.resources) implementation(libs.bundles.koin) - api(libs.koin.annotations) - implementation(libs.bundles.networking) implementation(libs.bundles.androidSupport) implementation(libs.coil) + implementation(libs.ktor.client.content.serialization.json) + implementation(libs.ktor.client.content.negotiation) + } } } \ No newline at end of file diff --git a/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/data/ProfilePickerStreamRepository.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/data/ProfilePickerStreamRepository.kt index 6474a36c..91e2404f 100644 --- a/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/data/ProfilePickerStreamRepository.kt +++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/data/ProfilePickerStreamRepository.kt @@ -8,13 +8,11 @@ import com.codandotv.streamplayerapp.profile.domain.toProfiles import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map -import org.koin.core.annotation.Factory interface ProfilePickerStreamRepository { suspend fun getProfiles(): Flow> } -@Factory class ProfilePickerStreamRepositoryImpl( private val service: ProfilePickerStreamService ) : ProfilePickerStreamRepository { diff --git a/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/domain/ProfilePickerStreamUseCase.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/domain/ProfilePickerStreamUseCase.kt index 490d855b..abf1a4a6 100644 --- a/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/domain/ProfilePickerStreamUseCase.kt +++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/domain/ProfilePickerStreamUseCase.kt @@ -3,7 +3,6 @@ package com.codandotv.streamplayerapp.profile.domain import com.codandotv.streamplayerapp.profile.data.ProfilePickerStreamRepository import kotlinx.coroutines.flow.Flow -import org.koin.core.annotation.Factory interface ProfilePickerStreamUseCase { suspend fun getProfile(): Flow> @@ -22,7 +21,6 @@ interface ProfilePickerStreamUseCase { ): Pair } -@Factory class ProfilePickerStreamUseCaseImpl( private val profilePickerStreamRepository: ProfilePickerStreamRepository ) : ProfilePickerStreamUseCase { diff --git a/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/screens/ProfilePickerStreamViewModel.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/screens/ProfilePickerStreamViewModel.kt index 5e1c9b59..75b5a2b6 100644 --- a/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/screens/ProfilePickerStreamViewModel.kt +++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/screens/ProfilePickerStreamViewModel.kt @@ -13,9 +13,7 @@ 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 -@KoinViewModel class ProfilePickerStreamViewModel( private val useCase: ProfilePickerStreamUseCase, ) : ViewModel(), DefaultLifecycleObserver { diff --git a/feature-search/build.gradle.kts b/feature-search/build.gradle.kts index fd7adf4e..415c6dc1 100644 --- a/feature-search/build.gradle.kts +++ b/feature-search/build.gradle.kts @@ -23,9 +23,11 @@ kotlin { implementation(compose.preview) implementation(libs.navigation.compose) implementation(libs.bundles.koin) - implementation(libs.bundles.networking) implementation(libs.coil) implementation(libs.bundles.androidSupport) + + implementation(libs.ktor.client.content.serialization.json) + implementation(libs.ktor.client.content.negotiation) } } } \ No newline at end of file diff --git a/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/model/ListSearchStreamResponse.kt b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/model/ListSearchStreamResponse.kt index 86baae53..88fa6d04 100644 --- a/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/model/ListSearchStreamResponse.kt +++ b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/model/ListSearchStreamResponse.kt @@ -1,22 +1,22 @@ package com.codandotv.streamplayerapp.feature_search.data.model -import com.squareup.moshi.Json +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable data class ListSearchStreamResponse( - @Json(name = "results") + @SerialName("results") val results: List ) { @Serializable data class SearchStreamResponse( - @Json(name = "id") + @SerialName("id") val id: Int, - @Json(name = "title") + @SerialName("title") val title: String, - @Json(name="overview") + @SerialName("overview") val overview: String, - @Json(name = "poster_path") + @SerialName("poster_path") val posterPath: String? = null ) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 03cb4d4f..35a417ab 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -29,7 +29,6 @@ viewmodel = "2.8.6" androidx_core_ktx = "1.13.1" #Networking -moshi = "1.14.0" okhttp = "4.12.0" ktor = "3.0.1" @@ -89,12 +88,9 @@ google_material = { group = "com.google.android.material", name = "material", ve 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 = { group = "io.insert-koin", name = "koin-annotations", version.ref = "koin-ksp" } -koin_ksp_compiler = { group = "io.insert-koin", name = "koin-ksp-compiler", version.ref = "koin-ksp" } koin_compose = { group = "io.insert-koin", name = "koin-androidx-compose", version.ref = "koin" } #Networking -moshi = { group = "com.squareup.moshi", name = "moshi-kotlin", version.ref = "moshi" } okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" } interceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" } @@ -116,7 +112,6 @@ ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junit" espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } [bundles] -networking = ["moshi", "okhttp", "interceptor", "ktor_client_core", "ktor_client_okhttp", "ktor_client_content_serialization_json", "ktor_client_content_negotiation", "ktor_client_logger", "ktor_client_auth"] koin = ["koin_android", "koin_compose"] test = ["junit", "mockk", "mockk_android", "viewmodel_test", "koin_test", "coroutines_test"] From 5905ff1a0ee7c6879bc23126b1bef4e81c4c386d Mon Sep 17 00:00:00 2001 From: Gabriel Bronzatti Moro Date: Mon, 3 Feb 2025 07:54:14 -0300 Subject: [PATCH 06/14] Format build.gradle dependencies --- composeApp/build.gradle.kts | 11 ++++++++--- core-local-storage/build.gradle.kts | 1 + core-navigation/build.gradle.kts | 2 +- core-networking/build.gradle.kts | 4 ++++ core-shared-ui/build.gradle.kts | 8 +++++--- core-shared/build.gradle.kts | 2 +- feature-detail/build.gradle.kts | 8 +++++--- feature-list-streams/build.gradle.kts | 10 +++++++--- feature-profile/build.gradle.kts | 6 ++++-- feature-search/build.gradle.kts | 9 ++++++--- gradle/libs.versions.toml | 4 ---- 11 files changed, 42 insertions(+), 23 deletions(-) diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index ee1a1a8c..183dc9ad 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -7,6 +7,9 @@ plugins { } kotlin { sourceSets { + androidMain.dependencies { + implementation(libs.koin.android) + } commonMain.dependencies { implementation(projects.featureListStreams) implementation(projects.featureDetail) @@ -19,13 +22,15 @@ kotlin { implementation(projects.coreLocalStorage) implementation(libs.navigation.compose) + implementation(compose.material3) implementation(compose.ui) implementation(compose.preview) - implementation(libs.bundles.koin) - implementation(libs.bundles.androidSupport) - implementation(libs.bundles.kotlin) + implementation(libs.lottie) + + implementation(libs.koin.core) + implementation(libs.koin.compose) } } } diff --git a/core-local-storage/build.gradle.kts b/core-local-storage/build.gradle.kts index 56092c54..cbc3aa8e 100644 --- a/core-local-storage/build.gradle.kts +++ b/core-local-storage/build.gradle.kts @@ -9,6 +9,7 @@ kotlin { commonMain.dependencies { implementation(libs.room.bundled) implementation(libs.room.runtime) + implementation(libs.koin.core) } } diff --git a/core-navigation/build.gradle.kts b/core-navigation/build.gradle.kts index d53cf82b..21fc6a77 100644 --- a/core-navigation/build.gradle.kts +++ b/core-navigation/build.gradle.kts @@ -8,8 +8,8 @@ plugins { kotlin { sourceSets { commonMain.dependencies { - implementation(libs.bundles.kotlin) implementation(libs.navigation.compose) + implementation(compose.material3) implementation(compose.components.resources) } diff --git a/core-networking/build.gradle.kts b/core-networking/build.gradle.kts index f30e603a..273aa0e4 100644 --- a/core-networking/build.gradle.kts +++ b/core-networking/build.gradle.kts @@ -21,19 +21,23 @@ kotlin { sourceSets { commonMain.dependencies { implementation(libs.kotlin.stdlib) + implementation(libs.koin.core) implementation(libs.ktor.client.core) implementation(libs.ktor.client.content.serialization.json) implementation(libs.ktor.client.content.negotiation) implementation(libs.ktor.client.logger) implementation(libs.ktor.client.auth) + implementation(compose.components.resources) implementation(compose.runtime) } androidMain.dependencies { implementation(libs.okhttp) + implementation(libs.interceptor) + implementation(libs.ktor.client.okhttp) } } diff --git a/core-shared-ui/build.gradle.kts b/core-shared-ui/build.gradle.kts index 2e111f7c..6f6a642f 100644 --- a/core-shared-ui/build.gradle.kts +++ b/core-shared-ui/build.gradle.kts @@ -9,16 +9,18 @@ kotlin { sourceSets { commonMain.dependencies { implementation(projects.coreShared) + implementation(compose.material3) implementation(compose.preview) implementation(compose.ui) implementation(compose.components.resources) + implementation(libs.navigation.compose) - implementation(libs.bundles.koin) - implementation(libs.bundles.kotlin) - implementation(libs.bundles.androidSupport) + implementation(libs.android.youtube.player) + implementation(libs.coil) + implementation(libs.paging.compose) } } diff --git a/core-shared/build.gradle.kts b/core-shared/build.gradle.kts index e4ee2dcd..692b2f9a 100644 --- a/core-shared/build.gradle.kts +++ b/core-shared/build.gradle.kts @@ -6,7 +6,7 @@ plugins { kotlin { sourceSets { commonMain.dependencies { - implementation(libs.bundles.koin) + implementation(libs.koin.core) } } } \ No newline at end of file diff --git a/feature-detail/build.gradle.kts b/feature-detail/build.gradle.kts index 0da20c8d..7b57b974 100644 --- a/feature-detail/build.gradle.kts +++ b/feature-detail/build.gradle.kts @@ -10,6 +10,8 @@ kotlin { sourceSets { commonMain.dependencies { implementation(libs.koin.core) + implementation(libs.koin.compose) + implementation(projects.coreNetworking) implementation(projects.coreNavigation) implementation(projects.coreShared) @@ -19,11 +21,11 @@ kotlin { implementation(compose.material3) implementation(compose.ui) implementation(compose.preview) + implementation(compose.components.resources) + implementation(libs.navigation.compose) - implementation(libs.bundles.koin) + implementation(libs.coil) - implementation(libs.bundles.androidSupport) - implementation(compose.components.resources) implementation(libs.ktor.client.content.serialization.json) implementation(libs.ktor.client.content.negotiation) diff --git a/feature-list-streams/build.gradle.kts b/feature-list-streams/build.gradle.kts index e8f628d6..da9998b1 100644 --- a/feature-list-streams/build.gradle.kts +++ b/feature-list-streams/build.gradle.kts @@ -9,8 +9,6 @@ plugins { kotlin { sourceSets { commonMain.dependencies { - implementation(libs.bundles.koin) - implementation(libs.paging.compose) implementation(projects.coreNetworking) implementation(projects.coreNavigation) implementation(projects.coreShared) @@ -21,12 +19,18 @@ kotlin { implementation(compose.material3) implementation(compose.ui) implementation(compose.preview) + + implementation(libs.paging.compose) + implementation(libs.navigation.compose) + implementation(libs.coil) - implementation(libs.bundles.androidSupport) implementation(libs.ktor.client.content.serialization.json) implementation(libs.ktor.client.content.negotiation) + + implementation(libs.koin.core) + implementation(libs.koin.compose) } } } \ No newline at end of file diff --git a/feature-profile/build.gradle.kts b/feature-profile/build.gradle.kts index 1dd0accc..781d5b15 100644 --- a/feature-profile/build.gradle.kts +++ b/feature-profile/build.gradle.kts @@ -13,18 +13,20 @@ kotlin { implementation(projects.coreNavigation) implementation(projects.coreShared) implementation(projects.coreSharedUi) + implementation(libs.navigation.compose) + implementation(compose.material3) implementation(compose.ui) implementation(compose.components.resources) - implementation(libs.bundles.koin) - implementation(libs.bundles.androidSupport) implementation(libs.coil) implementation(libs.ktor.client.content.serialization.json) implementation(libs.ktor.client.content.negotiation) + implementation(libs.koin.core) + implementation(libs.koin.compose) } } } \ No newline at end of file diff --git a/feature-search/build.gradle.kts b/feature-search/build.gradle.kts index 415c6dc1..08be24cd 100644 --- a/feature-search/build.gradle.kts +++ b/feature-search/build.gradle.kts @@ -10,7 +10,7 @@ kotlin { sourceSets { commonMain.dependencies { implementation(libs.paging.compose) - implementation(libs.koin.core) + implementation(projects.coreNetworking) implementation(projects.coreNavigation) implementation(projects.coreShared) @@ -21,13 +21,16 @@ kotlin { implementation(compose.material3) implementation(compose.ui) implementation(compose.preview) + implementation(libs.navigation.compose) - implementation(libs.bundles.koin) + implementation(libs.coil) - implementation(libs.bundles.androidSupport) implementation(libs.ktor.client.content.serialization.json) implementation(libs.ktor.client.content.negotiation) + + implementation(libs.koin.core) + implementation(libs.koin.compose) } } } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 35a417ab..c179d4cc 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -112,11 +112,7 @@ ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junit" espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } [bundles] -koin = ["koin_android", "koin_compose"] - test = ["junit", "mockk", "mockk_android", "viewmodel_test", "koin_test", "coroutines_test"] -androidSupport = ["androidx_core", "androidx_appcompat", "androidx_dynamicanimation", "google_material"] -kotlin = ["androidx_core", "kotlin_stdlib", "kotlin_reflect"] [plugins] android_application = { id = "com.android.application", version.ref = "android_gradle_plugin" } From 9eda7931f703261453f98c1f6540faed010611b2 Mon Sep 17 00:00:00 2001 From: Gabriel Bronzatti Moro Date: Mon, 3 Feb 2025 07:59:08 -0300 Subject: [PATCH 07/14] Dependencies cleanup --- gradle/libs.versions.toml | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c179d4cc..57383d29 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,7 +2,6 @@ kotlin = "2.0.21" android_gradle_plugin = "8.2.2" koin = "3.5.3" -koin-ksp = "1.3.1" ksp = "2.0.21-1.0.27" dokka = "1.9.10" @@ -19,15 +18,6 @@ androidx_core_testing = "2.2.0" mockk = "1.13.7" kotlinx-coroutines-test = "1.8.1" -#Android Support -android_core_ktx = "1.7.0" -androidx_appcompat = "1.7.0" -material = "1.12.0" -dynamic_animation = "1.0.0" -constraint_motion = "2.1.3" -viewmodel = "2.8.6" -androidx_core_ktx = "1.13.1" - #Networking okhttp = "4.12.0" ktor = "3.0.1" @@ -40,9 +30,6 @@ room = "2.7.0-alpha13" sqlite = "2.5.0-SNAPSHOT" android_youtube_player_version = "12.0.0" -uiAndroid = "1.7.5" -junit = "1.2.1" -espressoCore = "3.6.1" [libraries] @@ -50,40 +37,25 @@ kotlin_gradle_plugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-p android_gradle_plugin = { group = "com.android.tools.build", name = "gradle", version.ref = "android_gradle_plugin" } detekt-gradle-plugin = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detekt" } serialization = { module = "org.jetbrains.kotlin.plugin.serialization:org.jetbrains.kotlin.plugin.serialization.gradle.plugin", version.ref = "kotlin" } + com-google-devtools-ksp-gradle-plugin = { module = "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" } -#Kover kover-gradle-plugin = { module = "org.jetbrains.kotlinx:kover-gradle-plugin", version.ref = "kover" } -#Coil coil = { group = "io.coil-kt", name = "coil-compose", version.ref = "coil" } -#Lottie lottie = { group = "com.airbnb.android", name = "lottie-compose", version.ref = "lottie" } -# Kotlin kotlin_stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk7", version.ref = "kotlin" } -kotlin_reflect = { group = "org.jetbrains.kotlin", name = "kotlin-reflect", version.ref = "kotlin" } - -# Android Support -androidx_core = { group = "androidx.core", name = "core-ktx", version.ref = "androidx_core_ktx" } -androidx_appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "androidx_appcompat" } -androidx_dynamicanimation = { group = "androidx.dynamicanimation", name = "dynamicanimation", version.ref = "dynamic_animation" } -# Test junit = { group = "junit", name = "junit", version.ref = "test_junit" } mockk = { group = "io.mockk", name = "mockk", version.ref = "mockk" } mockk_android = { group = "io.mockk", name = "mockk-android", version.ref = "mockk" } viewmodel_test = { group = "androidx.arch.core", name = "core-testing", version.ref = "androidx_core_testing" } coroutines_test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "kotlinx-coroutines-test" } - -#Navigation navigation-compose = { module = "org.jetbrains.androidx.navigation:navigation-compose", version.ref = "navigation-compose-version" } paging-compose = { module = "androidx.paging:paging-compose", version.ref = "paging-compose" } -# Google -google_material = { group = "com.google.android.material", name = "material", version.ref = "material" } - # 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" } @@ -108,8 +80,6 @@ room_bundled = { group = "androidx.sqlite", name = "sqlite-bundled", version.ref android_youtube_player = { group = "com.pierfrancescosoffritti.androidyoutubeplayer", name = "core", version.ref = "android_youtube_player_version" } dokka = { group = "org.jetbrains.dokka", name = "android-documentation-plugin", version.ref = "dokka" } -ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junit" } -espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } [bundles] test = ["junit", "mockk", "mockk_android", "viewmodel_test", "koin_test", "coroutines_test"] @@ -130,5 +100,4 @@ ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" } kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } -detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" } buildkonfig_plugin = { id = "com.codingfeline.buildkonfig", version.ref = "buildkonfig" } From aeddeaeaca11feb7aadc2ae08eb42f6d30c32258 Mon Sep 17 00:00:00 2001 From: Gabriel Bronzatti Moro Date: Mon, 3 Feb 2025 08:03:56 -0300 Subject: [PATCH 08/14] VideoPlayer dependency isolation --- .../widget/PlayerComponent.android.kt | 95 ++++++++++++++++ .../core_shared_ui/widget/PlayerComponent.kt | 101 +----------------- 2 files changed, 98 insertions(+), 98 deletions(-) create mode 100644 core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.android.kt diff --git a/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.android.kt b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.android.kt new file mode 100644 index 00000000..51fc8e77 --- /dev/null +++ b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.android.kt @@ -0,0 +1,95 @@ +package com.codandotv.streamplayerapp.core_shared_ui.widget + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +import androidx.compose.ui.viewinterop.AndroidView +import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants +import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer +import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.YouTubePlayerListener +import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView + +@Composable +actual fun PlayerComponent(videoId: String, modifier: Modifier) { + + val context = LocalContext.current + + val youtubePlayerView = remember { + YouTubePlayerView(context).apply { + enableAutomaticInitialization = false + + addYouTubePlayerListener(object : YouTubePlayerListener { + override fun onApiChange(youTubePlayer: YouTubePlayer) = Unit + + override fun onCurrentSecond(youTubePlayer: YouTubePlayer, second: Float) = Unit + + override fun onError( + youTubePlayer: YouTubePlayer, + error: PlayerConstants.PlayerError + ) = Unit + + override fun onPlaybackQualityChange( + youTubePlayer: YouTubePlayer, + playbackQuality: PlayerConstants.PlaybackQuality + ) = Unit + + override fun onPlaybackRateChange( + youTubePlayer: YouTubePlayer, + playbackRate: PlayerConstants.PlaybackRate + ) = Unit + + override fun onReady(youTubePlayer: YouTubePlayer) { + youTubePlayer.loadVideo(videoId, 0f) + } + + override fun onStateChange( + youTubePlayer: YouTubePlayer, + state: PlayerConstants.PlayerState + ) = Unit + + override fun onVideoDuration(youTubePlayer: YouTubePlayer, duration: Float) = Unit + + override fun onVideoId(youTubePlayer: YouTubePlayer, videoId: String) = Unit + + override fun onVideoLoadedFraction( + youTubePlayer: YouTubePlayer, + loadedFraction: Float + ) = Unit + }) + } + } + + + Column( + modifier = modifier + .fillMaxSize() + ) { + Box { + AndroidView( + modifier = Modifier + .fillMaxWidth() + .height(200.dp) + .align(Alignment.TopCenter), + factory = { + youtubePlayerView + } + ) + } + } + + DisposableEffect( + key1 = Unit, + effect = { + onDispose { youtubePlayerView.release() } + }, + ) +} \ No newline at end of file diff --git a/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.kt b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.kt index 3013210d..e11d12a3 100644 --- a/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.kt +++ b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.kt @@ -1,105 +1,10 @@ +@file:Suppress("EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE") + package com.codandotv.streamplayerapp.core_shared_ui.widget -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.runtime.Composable -import androidx.compose.runtime.DisposableEffect -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.unit.dp -import androidx.compose.ui.viewinterop.AndroidView -import com.codandotv.streamplayerapp.core_shared_ui.theme.ThemePreviews -import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.PlayerConstants -import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.YouTubePlayer -import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.YouTubePlayerListener -import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView @Composable -fun PlayerComponent(videoId: String, modifier: Modifier = Modifier) { - - val context = LocalContext.current - - val youtubePlayerView = remember { - YouTubePlayerView(context).apply { - enableAutomaticInitialization = false - - addYouTubePlayerListener(object : YouTubePlayerListener { - override fun onApiChange(youTubePlayer: YouTubePlayer) = Unit - - override fun onCurrentSecond(youTubePlayer: YouTubePlayer, second: Float) = Unit - - override fun onError( - youTubePlayer: YouTubePlayer, - error: PlayerConstants.PlayerError - ) = Unit - - override fun onPlaybackQualityChange( - youTubePlayer: YouTubePlayer, - playbackQuality: PlayerConstants.PlaybackQuality - ) = Unit - - override fun onPlaybackRateChange( - youTubePlayer: YouTubePlayer, - playbackRate: PlayerConstants.PlaybackRate - ) = Unit - - override fun onReady(youTubePlayer: YouTubePlayer) { - youTubePlayer.loadVideo(videoId, 0f) - } +expect fun PlayerComponent(videoId: String, modifier: Modifier = Modifier) - override fun onStateChange( - youTubePlayer: YouTubePlayer, - state: PlayerConstants.PlayerState - ) = Unit - - override fun onVideoDuration(youTubePlayer: YouTubePlayer, duration: Float) = Unit - - override fun onVideoId(youTubePlayer: YouTubePlayer, videoId: String) = Unit - - override fun onVideoLoadedFraction( - youTubePlayer: YouTubePlayer, - loadedFraction: Float - ) = Unit - }) - } - } - - - Column( - modifier = modifier - .fillMaxSize() - ) { - Box { - AndroidView( - modifier = Modifier - .fillMaxWidth() - .height(200.dp) - .align(Alignment.TopCenter), - factory = { - youtubePlayerView - } - ) - } - } - - DisposableEffect( - key1 = Unit, - effect = { - onDispose { youtubePlayerView.release() } - }, - ) -} - -@Composable -@ThemePreviews -fun PlayerComponentPreview() { - PlayerComponent( - videoId = "BigBuckBunny.mp4", - modifier = Modifier.fillMaxWidth() - ) -} From 48b3de5b6f51543dcc4b3d7fa300a3d77d2a6eb2 Mon Sep 17 00:00:00 2001 From: Gabriel Bronzatti Moro Date: Mon, 3 Feb 2025 08:09:50 -0300 Subject: [PATCH 09/14] Enable iosTarget but not implementing it --- build-logic/src/main/java/Config.kt | 3 ++- .../com.streamplayer.application.gradle.kts | 3 +++ .../com.streamplayer.kmp-library.gradle.kts | 3 +++ .../java/extensions/KotlinMultiPlatformExt.kt | 17 +++++++++++++++++ core-local-storage/build.gradle.kts | 4 ---- 5 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 build-logic/src/main/java/extensions/KotlinMultiPlatformExt.kt diff --git a/build-logic/src/main/java/Config.kt b/build-logic/src/main/java/Config.kt index e21583a3..2bcfd844 100644 --- a/build-logic/src/main/java/Config.kt +++ b/build-logic/src/main/java/Config.kt @@ -1,5 +1,6 @@ object Config { - const val applicationId = "com.codandotv.streamplayerapp" + const val appName = "streamplayerapp" + const val applicationId = "com.codandotv.$appName" const val compileSdkVersion = 34 const val minSdkVersion = 24 const val targetSdkVersion = 34 diff --git a/build-logic/src/main/java/com.streamplayer.application.gradle.kts b/build-logic/src/main/java/com.streamplayer.application.gradle.kts index b1bcd23f..3c0fac6e 100644 --- a/build-logic/src/main/java/com.streamplayer.application.gradle.kts +++ b/build-logic/src/main/java/com.streamplayer.application.gradle.kts @@ -2,6 +2,7 @@ import extensions.dokkaPlugin import extensions.getLibrary +import extensions.iosTarget import extensions.setupAndroidDefaultConfig import extensions.setupCompileOptions import extensions.setupPackingOptions @@ -28,6 +29,8 @@ kotlin { jvmTarget.set(JvmTarget.JVM_17) } } + + iosTarget() } android { diff --git a/build-logic/src/main/java/com.streamplayer.kmp-library.gradle.kts b/build-logic/src/main/java/com.streamplayer.kmp-library.gradle.kts index d865de17..5d5d4c7b 100644 --- a/build-logic/src/main/java/com.streamplayer.kmp-library.gradle.kts +++ b/build-logic/src/main/java/com.streamplayer.kmp-library.gradle.kts @@ -2,6 +2,7 @@ import extensions.dokkaPlugin import extensions.getLibrary +import extensions.iosTarget import extensions.setupAndroidDefaultConfig import extensions.setupCompileOptions import extensions.setupNameSpace @@ -29,6 +30,8 @@ kotlin { jvmTarget.set(JvmTarget.JVM_17) } } + + iosTarget() } android { diff --git a/build-logic/src/main/java/extensions/KotlinMultiPlatformExt.kt b/build-logic/src/main/java/extensions/KotlinMultiPlatformExt.kt new file mode 100644 index 00000000..bd263ef0 --- /dev/null +++ b/build-logic/src/main/java/extensions/KotlinMultiPlatformExt.kt @@ -0,0 +1,17 @@ +package extensions + +import Config +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension + +fun KotlinMultiplatformExtension.iosTarget() { + listOf( + iosX64(), + iosArm64(), + iosSimulatorArm64() + ).forEach { iosTarget -> + iosTarget.binaries.framework { + baseName = Config.appName + isStatic = true + } + } +} diff --git a/core-local-storage/build.gradle.kts b/core-local-storage/build.gradle.kts index cbc3aa8e..2ffd79e4 100644 --- a/core-local-storage/build.gradle.kts +++ b/core-local-storage/build.gradle.kts @@ -19,10 +19,6 @@ dependencies { add("kspAndroid", libs.room.compiler) } -configurations.implementation{ - exclude(group = "com.intellij", module = "annotations") -} - room { schemaDirectory("$projectDir/schemas") } From 78783ab30c92d80c8954dd33dc9fdbd1fd690594 Mon Sep 17 00:00:00 2001 From: Gabriel Bronzatti Moro Date: Mon, 3 Feb 2025 08:18:42 -0300 Subject: [PATCH 10/14] Lottie is also android specific --- composeApp/build.gradle.kts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index 183dc9ad..97f3e978 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -9,6 +9,7 @@ kotlin { sourceSets { androidMain.dependencies { implementation(libs.koin.android) + implementation(libs.lottie) } commonMain.dependencies { implementation(projects.featureListStreams) @@ -27,8 +28,6 @@ kotlin { implementation(compose.ui) implementation(compose.preview) - implementation(libs.lottie) - implementation(libs.koin.core) implementation(libs.koin.compose) } From 45264b748afca10533f1781fd6f7f78cb05d0d6d Mon Sep 17 00:00:00 2001 From: Gabriel Bronzatti Moro Date: Wed, 5 Feb 2025 16:04:33 -0300 Subject: [PATCH 11/14] Bringing back the build configs variables --- build-logic/src/main/java/Config.kt | 9 +++++++-- core-networking/build.gradle.kts | 12 +++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/build-logic/src/main/java/Config.kt b/build-logic/src/main/java/Config.kt index 2bcfd844..6624f13c 100644 --- a/build-logic/src/main/java/Config.kt +++ b/build-logic/src/main/java/Config.kt @@ -9,13 +9,18 @@ object Config { const val testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" object BuildField { - const val host = "https://api.themoviedb.org/3/" - const val api_profile = "https://demo3364084.mockable.io/" + const val host_debug = "https://api.themoviedb.org/3/" + const val host_release = "https://api.themoviedb.org/3/" + const val api_profile_debug = "https://demo3364084.mockable.io/" + const val api_profile_release = "https://demo3364084.mockable.io/" private const val tmdb_token_name_debug = "TMDB_BEARER_TOKEN_DEBUG" + private const val tmdb_token_name_release = "TMDB_BEARER_TOKEN_RELEASE" private const val bearear_without_environment = "eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJiNDg2NWM4YTAzNzhmM2I4NjI0OWU1ZjNiYWFiMjU2NyIsInN1YiI6IjY0Mjk4YTg5YTNlNGJhMWM0NDgzM2U4OCIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.9cIxv29vkaZ2yW88DIFRUFK_nXbK2b6KS8t96kA8WAE" val api_bearer = System.getenv(tmdb_token_name_debug) ?: bearear_without_environment + val api_bearer_debug = System.getenv(tmdb_token_name_debug) ?: bearear_without_environment + val api_bearer_release = System.getenv(tmdb_token_name_release) ?: bearear_without_environment } } \ No newline at end of file diff --git a/core-networking/build.gradle.kts b/core-networking/build.gradle.kts index 273aa0e4..4bea4636 100644 --- a/core-networking/build.gradle.kts +++ b/core-networking/build.gradle.kts @@ -11,9 +11,15 @@ buildkonfig { packageName = "core.networking" defaultConfigs { - buildConfigField(FieldSpec.Type.STRING, "HOST", Config.BuildField.host) - buildConfigField(FieldSpec.Type.STRING, "API_BEARER_AUTH", Config.BuildField.api_bearer) - buildConfigField(FieldSpec.Type.STRING, "PROFILE", Config.BuildField.api_profile) + buildConfigField(FieldSpec.Type.STRING, "HOST", Config.BuildField.host_debug) + buildConfigField(FieldSpec.Type.STRING, "API_BEARER_AUTH", Config.BuildField.api_bearer_debug) + buildConfigField(FieldSpec.Type.STRING, "PROFILE", Config.BuildField.api_profile_debug) + } + + defaultConfigs("release") { + buildConfigField(FieldSpec.Type.STRING, "HOST", Config.BuildField.host_release) + buildConfigField(FieldSpec.Type.STRING, "API_BEARER_AUTH", Config.BuildField.api_bearer_release) + buildConfigField(FieldSpec.Type.STRING, "PROFILE", Config.BuildField.api_profile_release) } } From 3831391de3cd28dd107ddb8892c250bbb6f8cdfa Mon Sep 17 00:00:00 2001 From: Gabriel Bronzatti Moro Date: Wed, 5 Feb 2025 16:05:01 -0300 Subject: [PATCH 12/14] Bringing back the ksp configuration for iOS --- core-local-storage/build.gradle.kts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core-local-storage/build.gradle.kts b/core-local-storage/build.gradle.kts index 2ffd79e4..408d1805 100644 --- a/core-local-storage/build.gradle.kts +++ b/core-local-storage/build.gradle.kts @@ -17,6 +17,9 @@ kotlin { dependencies { add("kspAndroid", libs.room.compiler) + add("kspIosSimulatorArm64", libs.room.compiler) + add("kspIosX64", libs.room.compiler) + add("kspIosArm64", libs.room.compiler) } room { From c45120d9eee3e52bfba78352fd7a11783ef8681a Mon Sep 17 00:00:00 2001 From: Gabriel Bronzatti Moro Date: Wed, 5 Feb 2025 16:08:13 -0300 Subject: [PATCH 13/14] Add platform suffix to the httpClientEngineProvider --- ...android.kt => HttpClientEngineProviderPlatform.android.kt} | 2 +- ...tEngineProvider.kt => HttpClientEngineProviderPlatform.kt} | 2 +- .../streamplayerapp/core_networking/di/NetworkModule.kt | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename core-networking/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_networking/{HttpClientEngineProvider.android.kt => HttpClientEngineProviderPlatform.android.kt} (69%) rename core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/{HttpClientEngineProvider.kt => HttpClientEngineProviderPlatform.kt} (74%) diff --git a/core-networking/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProvider.android.kt b/core-networking/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProviderPlatform.android.kt similarity index 69% rename from core-networking/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProvider.android.kt rename to core-networking/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProviderPlatform.android.kt index 04598d01..5373464e 100644 --- a/core-networking/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProvider.android.kt +++ b/core-networking/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProviderPlatform.android.kt @@ -4,4 +4,4 @@ import io.ktor.client.engine.HttpClientEngine import io.ktor.client.engine.okhttp.OkHttpConfig import io.ktor.client.engine.okhttp.OkHttpEngine -actual fun httpClientEngine() : HttpClientEngine = OkHttpEngine(OkHttpConfig()) \ No newline at end of file +actual fun httpClientEnginePlatform() : HttpClientEngine = OkHttpEngine(OkHttpConfig()) \ No newline at end of file diff --git a/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProvider.kt b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProviderPlatform.kt similarity index 74% rename from core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProvider.kt rename to core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProviderPlatform.kt index a8f99a4a..b28059f0 100644 --- a/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProvider.kt +++ b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProviderPlatform.kt @@ -4,4 +4,4 @@ package com.codandotv.streamplayerapp.core_networking import io.ktor.client.engine.HttpClientEngine -expect fun httpClientEngine(): HttpClientEngine \ No newline at end of file +expect fun httpClientEnginePlatform(): HttpClientEngine \ No newline at end of file diff --git a/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/di/NetworkModule.kt b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/di/NetworkModule.kt index aca7f32e..002e7d7d 100644 --- a/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/di/NetworkModule.kt +++ b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/di/NetworkModule.kt @@ -2,7 +2,7 @@ package com.codandotv.streamplayerapp.core_networking.di import android.util.Log import com.codandotv.streamplayerapp.core_networking.di.Network.TIMEOUT -import com.codandotv.streamplayerapp.core_networking.httpClientEngine +import com.codandotv.streamplayerapp.core_networking.httpClientEnginePlatform import core.networking.BuildKonfig import io.ktor.client.HttpClient import io.ktor.client.plugins.HttpTimeout @@ -42,7 +42,7 @@ object NetworkModule { private fun provideKtorHttpClient( baseUrl: String, ): HttpClient { - return HttpClient(engine = httpClientEngine()) { + return HttpClient(engine = httpClientEnginePlatform()) { expectSuccess = false install(ContentNegotiation) { From bf705208a432fb3dacbe54b95c31949b03a05b9c Mon Sep 17 00:00:00 2001 From: Gabriel Bronzatti Moro Date: Wed, 5 Feb 2025 16:11:05 -0300 Subject: [PATCH 14/14] Add platform suffix to the Playercomponent --- .../core_shared_ui/widget/PlayerComponent.android.kt | 2 +- .../widget/{PlayerComponent.kt => PlayerComponentPlatform.kt} | 2 +- .../presentation/widget/DetailStreamImagePreview.kt | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/{PlayerComponent.kt => PlayerComponentPlatform.kt} (71%) diff --git a/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.android.kt b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.android.kt index 51fc8e77..56986e93 100644 --- a/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.android.kt +++ b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.android.kt @@ -19,7 +19,7 @@ import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.listeners.You import com.pierfrancescosoffritti.androidyoutubeplayer.core.player.views.YouTubePlayerView @Composable -actual fun PlayerComponent(videoId: String, modifier: Modifier) { +actual fun PlayerComponentPlatform(videoId: String, modifier: Modifier) { val context = LocalContext.current diff --git a/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.kt b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponentPlatform.kt similarity index 71% rename from core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.kt rename to core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponentPlatform.kt index e11d12a3..18dcb366 100644 --- a/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.kt +++ b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponentPlatform.kt @@ -6,5 +6,5 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @Composable -expect fun PlayerComponent(videoId: String, modifier: Modifier = Modifier) +expect fun PlayerComponentPlatform(videoId: String, modifier: Modifier = Modifier) diff --git a/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/widget/DetailStreamImagePreview.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/widget/DetailStreamImagePreview.kt index f21e7bf9..3d1fda7a 100644 --- a/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/widget/DetailStreamImagePreview.kt +++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/widget/DetailStreamImagePreview.kt @@ -16,7 +16,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.dp import coil.compose.AsyncImage -import com.codandotv.streamplayerapp.core_shared_ui.widget.PlayerComponent +import com.codandotv.streamplayerapp.core_shared_ui.widget.PlayerComponentPlatform import com.codandotv.streamplayerapp.feature_detail.presentation.screens.DetailStreamsUIState.DetailStreamsLoadedUIState import org.jetbrains.compose.resources.painterResource import streamplayerapp_kmp.feature_detail.generated.resources.Res @@ -37,7 +37,7 @@ fun DetailStreamImagePreview( contentAlignment = Alignment.Center ) { if (showPlayer) { - PlayerComponent( + PlayerComponentPlatform( videoId = uiState.videoId ?: "" ) } else {