diff --git a/.gitignore b/.gitignore
index bd6785e4..e599ccf5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,4 +13,5 @@
/captures
.externalNativeBuild
.cxx
+.kotlin
local.properties
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
deleted file mode 100644
index 4292f07d..00000000
--- a/app/build.gradle.kts
+++ /dev/null
@@ -1,31 +0,0 @@
-@file:Suppress("UnstableApiUsage")
-
-plugins {
- id("com.streamplayer.application")
-}
-
-dependencies {
- implementation(projects.featureFavorites)
- implementation(projects.featureListStreams)
- implementation(projects.featureProfile)
- implementation(projects.coreShared)
- implementation(projects.coreSharedUi)
- implementation(projects.coreNavigation)
- implementation(projects.coreNetworking)
- implementation(projects.coreLocalStorage)
-
- implementation(platform(libs.compose.bom))
- androidTestImplementation(platform(libs.compose.bom))
-
- implementation(libs.bundles.koin)
- implementation(libs.bundles.androidSupport)
- implementation(libs.bundles.compose)
- implementation(libs.bundles.kotlin)
-
- implementation(libs.lottie)
- implementation(libs.lottie)
- testImplementation(libs.bundles.test)
-
- // Kover - Combined report
- rootProject.subprojects.forEach { kover(it) }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/codandotv/streamplayerapp/splah/presentation/screens/SplashScreen.kt b/app/src/main/java/com/codandotv/streamplayerapp/splah/presentation/screens/SplashScreen.kt
deleted file mode 100644
index f08c7848..00000000
--- a/app/src/main/java/com/codandotv/streamplayerapp/splah/presentation/screens/SplashScreen.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-package com.codandotv.streamplayerapp.splah.presentation.screens
-
-import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.tooling.preview.Preview
-import com.airbnb.lottie.compose.LottieAnimation
-import com.airbnb.lottie.compose.LottieCompositionSpec
-import com.airbnb.lottie.compose.animateLottieCompositionAsState
-import com.airbnb.lottie.compose.rememberLottieComposition
-import com.codandotv.streamplayerapp.core.shared.ui.R as SharedUiR
-
-@Composable
-fun SplashScreen(
- onAnimationFinished: () -> Unit
-) {
- Column(
- modifier = Modifier.fillMaxSize()
- ) {
- Box(
- contentAlignment = Alignment.Center,
- modifier = Modifier
- .fillMaxSize()
- .background(Color.Black)
- ) {
- val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(SharedUiR.raw.logo))
- val logoAnimationState = animateLottieCompositionAsState(composition = composition)
- LottieAnimation(composition = composition, progress = { logoAnimationState.progress })
- if (logoAnimationState.isAtEnd && logoAnimationState.isPlaying) {
- onAnimationFinished()
- }
- }
- }
-}
-
-@Composable
-@Preview
-fun SplashScreenPreview() {
- SplashScreen(onAnimationFinished = {})
-}
\ No newline at end of file
diff --git a/app/src/main/res/xml/backup_rules.xml b/app/src/main/res/xml/backup_rules.xml
deleted file mode 100644
index fa0f996d..00000000
--- a/app/src/main/res/xml/backup_rules.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml
deleted file mode 100644
index 9ee9997b..00000000
--- a/app/src/main/res/xml/data_extraction_rules.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/test/java/com/codandotv/streamplayerapp/ExampleUnitTest.kt b/app/src/test/java/com/codandotv/streamplayerapp/ExampleUnitTest.kt
deleted file mode 100644
index e83e0c8a..00000000
--- a/app/src/test/java/com/codandotv/streamplayerapp/ExampleUnitTest.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.codandotv.streamplayerapp
-
-import org.junit.Test
-
-import org.junit.Assert.assertEquals
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * See [testing documentation](http://d.android.com/tools/testing).
- */
-class ExampleUnitTest {
- @Test
- fun addition_isCorrect() {
- assertEquals(4, 2 + 2)
- }
-}
\ No newline at end of file
diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts
index eaf67121..8377f141 100644
--- a/build-logic/build.gradle.kts
+++ b/build-logic/build.gradle.kts
@@ -6,8 +6,10 @@ plugins {
}
repositories {
- mavenCentral()
google()
+ mavenCentral()
+ gradlePluginPortal()
+ maven(url = "https://plugins.gradle.org/m2/")
}
dependencies {
@@ -15,4 +17,6 @@ dependencies {
implementation(libs.kotlin.gradle.plugin)
implementation(libs.kover.gradle.plugin)
implementation(libs.detekt.gradle.plugin)
+ implementation(libs.serialization)
+ implementation(libs.com.google.devtools.ksp.gradle.plugin)
}
\ No newline at end of file
diff --git a/build-logic/src/main/java/Config.kt b/build-logic/src/main/java/Config.kt
index 2ba49cd2..ede08d28 100644
--- a/build-logic/src/main/java/Config.kt
+++ b/build-logic/src/main/java/Config.kt
@@ -1,24 +1,26 @@
object Config {
- const val applicationId = "com.codandotv.streamplayerapp"
- const val compileSdkVersion = 34
- const val minSdkVersion = 24
- const val targetSdkVersion = 34
+ const val appName = "streamplayerapp"
+ const val applicationId = "com.codandotv.$appName"
+ const val compileSdkVersion = 35
+ const val minSdkVersion = 28
+ const val targetSdkVersion = 35
const val versionName = "1.0"
const val versionCode = 1
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_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_debug = "\"Bearer ${System.getenv(tmdb_token_name_debug) ?: bearear_without_environment}\""
- val api_bearer_release = "\"Bearer ${System.getenv(tmdb_token_name_release) ?: bearear_without_environment}\""
+ 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/build-logic/src/main/java/Keys.kt b/build-logic/src/main/java/Keys.kt
deleted file mode 100644
index 4475b22e..00000000
--- a/build-logic/src/main/java/Keys.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-object Keys {
- private const val default_tmdb_token = "eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJiNDg2NWM4YTAzNzhmM2I4NjI0OWU1ZjNiYWFiMjU2NyIsInN1YiI6IjY0Mjk4YTg5YTNlNGJhMWM0NDgzM2U4OCIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.9cIxv29vkaZ2yW88DIFRUFK_nXbK2b6KS8t96kA8WAE"
- private const val tmdb_token_name_debug = "TMDB_BEARER_TOKEN_DEBUG"
- private const val tmdb_token_name_release = "TMDB_BEARER_TOKEN_RELEASE"
-
- object BuildField {
- val api_bearer_debug =
- "\"Bearer ${System.getenv(tmdb_token_name_debug) ?: default_tmdb_token}\""
- val api_bearer_release =
- "\"Bearer ${System.getenv(tmdb_token_name_release) ?: default_tmdb_token}\""
- }
-}
\ No newline at end of file
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 e5af04a1..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,16 +2,18 @@
import extensions.dokkaPlugin
import extensions.getLibrary
+import extensions.iosTarget
import extensions.setupAndroidDefaultConfig
import extensions.setupCompileOptions
-import extensions.setupCompose
import extensions.setupPackingOptions
+import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
+import org.jetbrains.kotlin.gradle.dsl.JvmTarget
val libs: VersionCatalog = extensions.getByType().named("libs")
plugins {
id("com.android.application")
- id("kotlin-android")
+ id("org.jetbrains.kotlin.multiplatform")
id("kotlin-kapt")
id("kotlin-parcelize")
id("com.streamplayer.dokka")
@@ -20,6 +22,16 @@ plugins {
}
val catalog: VersionCatalog = extensions.getByType().named("libs")
+kotlin {
+ androidTarget {
+ @OptIn(ExperimentalKotlinGradlePluginApi::class)
+ compilerOptions {
+ jvmTarget.set(JvmTarget.JVM_17)
+ }
+ }
+
+ iosTarget()
+}
android {
namespace = Config.applicationId
@@ -27,7 +39,6 @@ android {
setupCompileOptions()
setupPackingOptions()
setupAndroidDefaultConfig()
- setupCompose(catalog)
defaultConfig {
applicationId = Config.applicationId
diff --git a/build-logic/src/main/java/com.streamplayer.compose.gradle.kts b/build-logic/src/main/java/com.streamplayer.compose.gradle.kts
deleted file mode 100644
index c6542e3e..00000000
--- a/build-logic/src/main/java/com.streamplayer.compose.gradle.kts
+++ /dev/null
@@ -1,22 +0,0 @@
-@file:Suppress("UnstableApiUsage")
-import extensions.getBundle
-import extensions.getLibrary
-import extensions.setupCompose
-
-plugins {
- id("com.streamplayer.android-library")
-}
-
-val libs: VersionCatalog = extensions.getByType().named("libs")
-
-android {
- setupCompose(libs)
-}
-
-dependencies {
- implementation(platform(libs.getLibrary("compose.bom")))
- androidTestImplementation(platform(libs.getLibrary("compose.bom")))
-
- implementation(libs.getBundle("compose"))
- debugImplementation(libs.getLibrary("compose.ui.tooling"))
-}
\ No newline at end of file
diff --git a/build-logic/src/main/java/com.streamplayer.android-library.gradle.kts b/build-logic/src/main/java/com.streamplayer.kmp-library.gradle.kts
similarity index 71%
rename from build-logic/src/main/java/com.streamplayer.android-library.gradle.kts
rename to build-logic/src/main/java/com.streamplayer.kmp-library.gradle.kts
index 6b0ea5af..5d5d4c7b 100644
--- a/build-logic/src/main/java/com.streamplayer.android-library.gradle.kts
+++ b/build-logic/src/main/java/com.streamplayer.kmp-library.gradle.kts
@@ -2,16 +2,20 @@
import extensions.dokkaPlugin
import extensions.getLibrary
+import extensions.iosTarget
import extensions.setupAndroidDefaultConfig
import extensions.setupCompileOptions
import extensions.setupNameSpace
import extensions.setupPackingOptions
+import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
+import org.jetbrains.kotlin.gradle.dsl.JvmTarget
-val libs: VersionCatalog = extensions.getByType().named("libs")
+val libs: VersionCatalog = extensions.getByType().named("libs")
plugins {
+ id("org.jetbrains.kotlin.multiplatform")
id("com.android.library")
- id("kotlin-android")
+ id("org.jetbrains.kotlin.plugin.serialization")
id("kotlin-kapt")
id("kotlin-parcelize")
id("com.streamplayer.dokka")
@@ -19,6 +23,17 @@ plugins {
id("com.streamplayer.detekt")
}
+kotlin {
+ androidTarget {
+ @OptIn(ExperimentalKotlinGradlePluginApi::class)
+ compilerOptions {
+ jvmTarget.set(JvmTarget.JVM_17)
+ }
+ }
+
+ iosTarget()
+}
+
android {
setupNameSpace(project)
@@ -44,4 +59,4 @@ android {
dependencies {
dokkaPlugin(libs.getLibrary("dokka"))
-}
\ No newline at end of file
+}
diff --git a/build-logic/src/main/java/extensions/CommonExtensions.kt b/build-logic/src/main/java/extensions/CommonExtensions.kt
index 84543ee2..a54f3d85 100644
--- a/build-logic/src/main/java/extensions/CommonExtensions.kt
+++ b/build-logic/src/main/java/extensions/CommonExtensions.kt
@@ -7,10 +7,10 @@ import com.android.build.api.dsl.CommonExtension
import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.artifacts.VersionCatalog
-import org.gradle.api.plugins.ExtensionAware
-import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.kotlin.dsl.getByType
-internal fun CommonExtension<*, *, *, *, *>.setupPackingOptions() {
+internal fun CommonExtension<*, *, *, *, *, *>.setupPackingOptions() {
packaging {
resources {
with(pickFirsts) {
@@ -26,7 +26,7 @@ internal fun CommonExtension<*, *, *, *, *>.setupPackingOptions() {
}
}
-internal fun CommonExtension<*, *, *, *, *>.setupAndroidDefaultConfig() {
+internal fun CommonExtension<*, *, *, *, *, *>.setupAndroidDefaultConfig() {
defaultConfig {
compileSdk = Config.compileSdkVersion
minSdk = Config.minSdkVersion
@@ -36,39 +36,14 @@ internal fun CommonExtension<*, *, *, *, *>.setupAndroidDefaultConfig() {
}
}
-internal fun CommonExtension<*, *, *, *, *>.setupCompileOptions() {
+internal fun CommonExtension<*, *, *, *, *, *>.setupCompileOptions() {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
-
- kotlinOptions {
- jvmTarget = "17"
- }
-}
-
-fun CommonExtension<*, *, *, *, *>.setupCompose(catalog: VersionCatalog) {
- buildFeatures {
- compose = true
- buildConfig = true
- }
-
- composeOptions {
- kotlinCompilerExtensionVersion = "${catalog.getVersion("compose")}"
- }
-
- packaging {
- resources {
- excludes.apply {
- add("META-INF/AL2.0")
- add("META-INF/LGPL2.1")
- }
- }
- }
}
-
-internal fun CommonExtension<*, *, *, *, *>.setupNameSpace(project: Project) {
+internal fun CommonExtension<*, *, *, *, *, *>.setupNameSpace(project: Project) {
val moduleName = project.displayName
.removePrefix("project ")
.replace(":", ".")
@@ -76,8 +51,12 @@ internal fun CommonExtension<*, *, *, *, *>.setupNameSpace(project: Project) {
.replace("-", ".")
namespace = "${Config.applicationId}$moduleName"
-}
-private fun CommonExtension<*, *, *, *, *>.kotlinOptions(block: KotlinJvmOptions.() -> Unit) {
- (this as ExtensionAware).extensions.configure("kotlinOptions", block)
+ println(">>>> $namespace")
}
+
+internal val Project.libs: VersionCatalog
+ get() {
+ return project.extensions.getByType()
+ .named("libs")
+ }
\ No newline at end of file
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/build-logic/src/main/java/extensions/VersionCatalog.kt b/build-logic/src/main/java/extensions/VersionCatalog.kt
index ee317e56..fcfdaf10 100644
--- a/build-logic/src/main/java/extensions/VersionCatalog.kt
+++ b/build-logic/src/main/java/extensions/VersionCatalog.kt
@@ -6,3 +6,11 @@ internal fun VersionCatalog.getLibrary(library: String) = findLibrary(library).g
internal fun VersionCatalog.getVersion(library: String) = findVersion(library).get()
internal fun VersionCatalog.getBundle(bundle: String) = findBundle(bundle).get()
+internal fun VersionCatalog.koinCoreDependency() = findLibrary("koin_core").get()
+
+internal fun VersionCatalog.koinAnnotationsDependency() = findLibrary("koin_annotations").get()
+
+internal fun VersionCatalog.koinComposeDependency() = findLibrary("koin_compose").get()
+
+internal fun VersionCatalog.koinCompiler() = findLibrary("koin_ksp_compiler").get()
+
diff --git a/build.gradle.kts b/build.gradle.kts
index df8846e7..4e1f6f7b 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -5,9 +5,14 @@ plugins {
alias(libs.plugins.android.application) apply false
alias(libs.plugins.android.library) apply false
alias(libs.plugins.kotlin.android) apply false
+ alias(libs.plugins.serialization) apply false
+ alias(libs.plugins.kotlin.multiplatform) apply false
+ alias(libs.plugins.jetbrains.compose) apply false
+ alias(libs.plugins.compose.compiler) apply false
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/build/kotlin/commonizedNativeDistributionLocation.txt b/build/kotlin/commonizedNativeDistributionLocation.txt
new file mode 100644
index 00000000..64f5ff0e
--- /dev/null
+++ b/build/kotlin/commonizedNativeDistributionLocation.txt
@@ -0,0 +1 @@
+/Users/rodrigo/.konan/kotlin-native-prebuilt-macos-aarch64-2.1.10/klib/commonized/2.1.10
\ No newline at end of file
diff --git a/app/.gitignore b/composeApp/.gitignore
similarity index 100%
rename from app/.gitignore
rename to composeApp/.gitignore
diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts
new file mode 100644
index 00000000..21c08c2b
--- /dev/null
+++ b/composeApp/build.gradle.kts
@@ -0,0 +1,40 @@
+@file:Suppress("UnstableApiUsage")
+
+plugins {
+ id("com.streamplayer.application")
+ alias(libs.plugins.jetbrains.compose)
+ alias(libs.plugins.compose.compiler)
+}
+kotlin {
+ sourceSets {
+ androidMain.dependencies {
+ implementation(libs.koin.android)
+ implementation(libs.lottie)
+ implementation(compose.preview)
+ }
+ commonMain.dependencies {
+ implementation(projects.featureListStreams)
+ implementation(projects.featureDetail)
+ implementation(projects.featureSearch)
+ implementation(projects.featureProfile)
+ implementation(projects.coreShared)
+ implementation(projects.coreSharedUi)
+ implementation(projects.coreNavigation)
+ implementation(projects.coreNetworking)
+ implementation(projects.coreLocalStorage)
+
+ implementation(libs.navigation.compose)
+
+ implementation(compose.material3)
+ implementation(compose.ui)
+ implementation(compose.components.resources)
+
+ implementation(libs.koin.core)
+ }
+ }
+}
+
+dependencies {
+ // Kover - Combined report
+ rootProject.subprojects.forEach { kover(it) }
+}
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/composeApp/proguard-rules.pro
similarity index 100%
rename from app/proguard-rules.pro
rename to composeApp/proguard-rules.pro
diff --git a/app/src/main/AndroidManifest.xml b/composeApp/src/androidMain/AndroidManifest.xml
similarity index 72%
rename from app/src/main/AndroidManifest.xml
rename to composeApp/src/androidMain/AndroidManifest.xml
index 43b331ce..a074f2bb 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/composeApp/src/androidMain/AndroidManifest.xml
@@ -3,16 +3,14 @@
+ android:name=".presentation.CustomApplication">
diff --git a/app/src/main/java/com/codandotv/streamplayerapp/CustomApplication.kt b/composeApp/src/androidMain/kotlin/com.codandotv.streamplayerapp/presentation/CustomApplication.kt
similarity index 88%
rename from app/src/main/java/com/codandotv/streamplayerapp/CustomApplication.kt
rename to composeApp/src/androidMain/kotlin/com.codandotv.streamplayerapp/presentation/CustomApplication.kt
index 9c565d56..8cbc1494 100644
--- a/app/src/main/java/com/codandotv/streamplayerapp/CustomApplication.kt
+++ b/composeApp/src/androidMain/kotlin/com.codandotv.streamplayerapp/presentation/CustomApplication.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp
+package com.codandotv.streamplayerapp.presentation
import android.app.Application
import com.codandotv.streamplayerapp.di.AppModule
diff --git a/composeApp/src/androidMain/kotlin/com.codandotv.streamplayerapp/presentation/MainActivity.kt b/composeApp/src/androidMain/kotlin/com.codandotv.streamplayerapp/presentation/MainActivity.kt
new file mode 100644
index 00000000..d3824ddd
--- /dev/null
+++ b/composeApp/src/androidMain/kotlin/com.codandotv.streamplayerapp/presentation/MainActivity.kt
@@ -0,0 +1,15 @@
+package com.codandotv.streamplayerapp.presentation
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import com.codandotv.streamplayerapp.StreamPlayerApp
+
+class MainActivity : ComponentActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContent {
+ StreamPlayerApp()
+ }
+ }
+}
diff --git a/composeApp/src/androidMain/kotlin/com.codandotv.streamplayerapp/presentation/components/LottieComponentPlatform.android.kt b/composeApp/src/androidMain/kotlin/com.codandotv.streamplayerapp/presentation/components/LottieComponentPlatform.android.kt
new file mode 100644
index 00000000..d7a7f74f
--- /dev/null
+++ b/composeApp/src/androidMain/kotlin/com.codandotv.streamplayerapp/presentation/components/LottieComponentPlatform.android.kt
@@ -0,0 +1,34 @@
+package com.codandotv.streamplayerapp.presentation.components
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Modifier
+import com.airbnb.lottie.compose.LottieAnimation
+import com.airbnb.lottie.compose.LottieCompositionSpec
+import com.airbnb.lottie.compose.animateLottieCompositionAsState
+import com.airbnb.lottie.compose.rememberLottieComposition
+
+@Composable
+actual fun LottieComponent(
+ jsonString: String,
+ modifier: Modifier,
+ onAnimationFinished: () -> Unit
+) {
+ val composition by rememberLottieComposition(
+ spec = LottieCompositionSpec.JsonString(
+ jsonString = jsonString
+ )
+ )
+ val logoAnimationState = animateLottieCompositionAsState(
+ composition = composition
+ )
+
+ LottieAnimation(
+ composition = composition,
+ progress = { logoAnimationState.progress }
+ )
+
+ if (logoAnimationState.isAtEnd && logoAnimationState.isPlaying) {
+ onAnimationFinished()
+ }
+}
diff --git a/composeApp/src/commonMain/composeResources/files/lottie/logo.json b/composeApp/src/commonMain/composeResources/files/lottie/logo.json
new file mode 100644
index 00000000..32536ffa
--- /dev/null
+++ b/composeApp/src/commonMain/composeResources/files/lottie/logo.json
@@ -0,0 +1,8141 @@
+{
+ "v": "5.5.7",
+ "meta": {
+ "g": "LottieFiles AE 0.1.21",
+ "a": "",
+ "k": "",
+ "d": "",
+ "tc": "#FFFFFF"
+ },
+ "fr": 60,
+ "ip": 0,
+ "op": 306,
+ "w": 512,
+ "h": 512,
+ "nm": "Nettflix",
+ "ddd": 0,
+ "assets": [],
+ "layers": [
+ {
+ "ddd": 0,
+ "ind": 1,
+ "ty": 4,
+ "nm": "Big N 1",
+ "sr": 1,
+ "ks": {
+ "o": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.667
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.333
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 18,
+ "s": [
+ 0
+ ]
+ },
+ {
+ "i": {
+ "x": [
+ 0.833
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.167
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 28.666,
+ "s": [
+ 100
+ ]
+ },
+ {
+ "i": {
+ "x": [
+ 1
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.612
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 114,
+ "s": [
+ 100
+ ]
+ },
+ {
+ "t": 142,
+ "s": [
+ 0
+ ]
+ }
+ ],
+ "ix": 11
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 10
+ },
+ "p": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.455,
+ "y": 1
+ },
+ "o": {
+ "x": 0.684,
+ "y": 0
+ },
+ "t": 104,
+ "s": [
+ 256,
+ 256,
+ 0
+ ],
+ "to": [
+ -24.667,
+ 0,
+ 0
+ ],
+ "ti": [
+ 24.667,
+ 0,
+ 0
+ ]
+ },
+ {
+ "t": 154.74609375,
+ "s": [
+ 108,
+ 256,
+ 0
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0.209,
+ 0.143,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.461,
+ 0.461,
+ 0.667
+ ],
+ "y": [
+ 1,
+ 1,
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.655,
+ 0.655,
+ 0.333
+ ],
+ "y": [
+ 0,
+ 0,
+ 0
+ ]
+ },
+ "t": 46,
+ "s": [
+ 66,
+ 66,
+ 100
+ ]
+ },
+ {
+ "t": 104,
+ "s": [
+ 21,
+ 21,
+ 100
+ ]
+ }
+ ],
+ "ix": 6
+ }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.252,
+ "y": 1
+ },
+ "o": {
+ "x": 0.434,
+ "y": 0
+ },
+ "t": 18,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 42.684,
+ 1.078
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 120.607,
+ 218.722
+ ],
+ [
+ 31.805,
+ 211.525
+ ],
+ [
+ 31.977,
+ 211.212
+ ],
+ [
+ 120.318,
+ 218.496
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "i": {
+ "x": 0.833,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0
+ },
+ "t": 46,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 42.684,
+ 1.078
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -34.128,
+ -218.21
+ ],
+ [
+ -119.9,
+ -218.21
+ ],
+ [
+ 31.977,
+ 211.212
+ ],
+ [
+ 120.318,
+ 218.496
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "i": {
+ "x": 0.833,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0
+ },
+ "t": 124,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 42.684,
+ 1.078
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -34.128,
+ -218.21
+ ],
+ [
+ -119.9,
+ -218.21
+ ],
+ [
+ 31.977,
+ 211.212
+ ],
+ [
+ 120.318,
+ 218.496
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "t": 156,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 44.422,
+ -6.307
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -47.223,
+ -218.706
+ ],
+ [
+ -102.043,
+ -218.706
+ ],
+ [
+ 41.501,
+ 198.117
+ ],
+ [
+ 102.46,
+ 192.802
+ ]
+ ],
+ "c": true
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "fl",
+ "c": {
+ "a": 0,
+ "k": [
+ 0.898039215686,
+ 0.035294117647,
+ 0.078431372549,
+ 1
+ ],
+ "ix": 4
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 5
+ },
+ "r": 1,
+ "bm": 0,
+ "nm": "Fill 1",
+ "mn": "ADBE Vector Graphic - Fill",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Big N 1",
+ "np": 2,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ }
+ ],
+ "ip": 0,
+ "op": 3868,
+ "st": 0,
+ "bm": 0
+ },
+ {
+ "ddd": 0,
+ "ind": 2,
+ "ty": 4,
+ "nm": "Big N 2 matte",
+ "parent": 1,
+ "td": 1,
+ "sr": 1,
+ "ks": {
+ "o": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.667
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.333
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 0,
+ "s": [
+ 0
+ ]
+ },
+ {
+ "i": {
+ "x": [
+ 0.833
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.333
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 10.666,
+ "s": [
+ 100
+ ]
+ },
+ {
+ "i": {
+ "x": [
+ 1
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.612
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 114,
+ "s": [
+ 100
+ ]
+ },
+ {
+ "t": 142,
+ "s": [
+ 0
+ ]
+ }
+ ],
+ "ix": 11
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 10
+ },
+ "p": {
+ "a": 0,
+ "k": [
+ 77.223,
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 77.223,
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100,
+ 100
+ ],
+ "ix": 6
+ }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.252,
+ "y": 1
+ },
+ "o": {
+ "x": 0.434,
+ "y": 0
+ },
+ "t": 0,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 1.198,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.901,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 34.099,
+ -359.119
+ ],
+ [
+ 120.288,
+ -359.43
+ ],
+ [
+ 120.49,
+ -359.888
+ ],
+ [
+ 33.164,
+ -359.117
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "i": {
+ "x": 0.833,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0
+ },
+ "t": 24,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 28.673,
+ 0.875
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -28.673,
+ -3.601
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 34.128,
+ -218.21
+ ],
+ [
+ 120.318,
+ -218.521
+ ],
+ [
+ 120.318,
+ 218.521
+ ],
+ [
+ 34.128,
+ 211.337
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "i": {
+ "x": 0.833,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0
+ },
+ "t": 124,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 28.673,
+ 0.875
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -28.673,
+ -3.601
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 34.128,
+ -218.21
+ ],
+ [
+ 120.318,
+ -218.521
+ ],
+ [
+ 120.318,
+ 218.521
+ ],
+ [
+ 34.128,
+ 211.337
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "t": 156,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 28.249,
+ -4.53
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -27.545,
+ 1.34
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 48.414,
+ -218.706
+ ],
+ [
+ 114.365,
+ -217.965
+ ],
+ [
+ 116.869,
+ 194.041
+ ],
+ [
+ 44.408,
+ 201.102
+ ]
+ ],
+ "c": true
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "fl",
+ "c": {
+ "a": 0,
+ "k": [
+ 0.694117647059,
+ 0.023529411765,
+ 0.058823529412,
+ 1
+ ],
+ "ix": 4
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 5
+ },
+ "r": 1,
+ "bm": 0,
+ "nm": "Fill 1",
+ "mn": "ADBE Vector Graphic - Fill",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Big N 2",
+ "np": 2,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ }
+ ],
+ "ip": 0,
+ "op": 3868,
+ "st": 0,
+ "bm": 0
+ },
+ {
+ "ddd": 0,
+ "ind": 3,
+ "ty": 4,
+ "nm": "Big N 1 shadow 2",
+ "tt": 1,
+ "sr": 1,
+ "ks": {
+ "o": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.667
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.333
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 18,
+ "s": [
+ 0
+ ]
+ },
+ {
+ "i": {
+ "x": [
+ 0.833
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.167
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 28.666,
+ "s": [
+ 100
+ ]
+ },
+ {
+ "i": {
+ "x": [
+ 1
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.612
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 114,
+ "s": [
+ 100
+ ]
+ },
+ {
+ "t": 142,
+ "s": [
+ 0
+ ]
+ }
+ ],
+ "ix": 11
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 10
+ },
+ "p": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.455,
+ "y": 1
+ },
+ "o": {
+ "x": 0.684,
+ "y": 0
+ },
+ "t": 104,
+ "s": [
+ 256,
+ 256,
+ 0
+ ],
+ "to": [
+ -24.667,
+ 0,
+ 0
+ ],
+ "ti": [
+ 24.667,
+ 0,
+ 0
+ ]
+ },
+ {
+ "t": 154.74609375,
+ "s": [
+ 108,
+ 256,
+ 0
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0.209,
+ 0.143,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.461,
+ 0.461,
+ 0.667
+ ],
+ "y": [
+ 1,
+ 1,
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.655,
+ 0.655,
+ 0.333
+ ],
+ "y": [
+ 0,
+ 0,
+ 0
+ ]
+ },
+ "t": 46,
+ "s": [
+ 66,
+ 66,
+ 100
+ ]
+ },
+ {
+ "t": 104,
+ "s": [
+ 21,
+ 21,
+ 100
+ ]
+ }
+ ],
+ "ix": 6
+ }
+ },
+ "ao": 0,
+ "ef": [
+ {
+ "ty": 25,
+ "nm": "Drop Shadow",
+ "np": 8,
+ "mn": "ADBE Drop Shadow",
+ "ix": 1,
+ "en": 1,
+ "ef": [
+ {
+ "ty": 2,
+ "nm": "Shadow Color",
+ "mn": "ADBE Drop Shadow-0001",
+ "ix": 1,
+ "v": {
+ "a": 0,
+ "k": [
+ 0.086274512112,
+ 0,
+ 0.0074725952,
+ 1
+ ],
+ "ix": 1
+ }
+ },
+ {
+ "ty": 0,
+ "nm": "Opacity",
+ "mn": "ADBE Drop Shadow-0002",
+ "ix": 2,
+ "v": {
+ "a": 0,
+ "k": 178.5,
+ "ix": 2
+ }
+ },
+ {
+ "ty": 0,
+ "nm": "Direction",
+ "mn": "ADBE Drop Shadow-0003",
+ "ix": 3,
+ "v": {
+ "a": 0,
+ "k": 0,
+ "ix": 3
+ }
+ },
+ {
+ "ty": 0,
+ "nm": "Distance",
+ "mn": "ADBE Drop Shadow-0004",
+ "ix": 4,
+ "v": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ }
+ },
+ {
+ "ty": 0,
+ "nm": "Softness",
+ "mn": "ADBE Drop Shadow-0005",
+ "ix": 5,
+ "v": {
+ "a": 0,
+ "k": 100,
+ "ix": 5
+ }
+ },
+ {
+ "ty": 7,
+ "nm": "Shadow Only",
+ "mn": "ADBE Drop Shadow-0006",
+ "ix": 6,
+ "v": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ }
+ }
+ ]
+ }
+ ],
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.252,
+ "y": 1
+ },
+ "o": {
+ "x": 0.434,
+ "y": 0
+ },
+ "t": 18,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 42.684,
+ 1.078
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 120.607,
+ 218.722
+ ],
+ [
+ 31.805,
+ 211.525
+ ],
+ [
+ 31.977,
+ 211.212
+ ],
+ [
+ 120.318,
+ 218.496
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "i": {
+ "x": 0.833,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0
+ },
+ "t": 46,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 42.684,
+ 1.078
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -34.128,
+ -218.21
+ ],
+ [
+ -119.9,
+ -218.21
+ ],
+ [
+ 31.977,
+ 211.212
+ ],
+ [
+ 120.318,
+ 218.496
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "i": {
+ "x": 0.833,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0
+ },
+ "t": 124,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 42.684,
+ 1.078
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -34.128,
+ -218.21
+ ],
+ [
+ -119.9,
+ -218.21
+ ],
+ [
+ 31.977,
+ 211.212
+ ],
+ [
+ 120.318,
+ 218.496
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "t": 156,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 44.422,
+ -6.307
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -47.223,
+ -218.706
+ ],
+ [
+ -102.043,
+ -218.706
+ ],
+ [
+ 41.501,
+ 198.117
+ ],
+ [
+ 102.46,
+ 192.802
+ ]
+ ],
+ "c": true
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "fl",
+ "c": {
+ "a": 0,
+ "k": [
+ 0.898039215686,
+ 0.035294117647,
+ 0.078431372549,
+ 1
+ ],
+ "ix": 4
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 5
+ },
+ "r": 1,
+ "bm": 0,
+ "nm": "Fill 1",
+ "mn": "ADBE Vector Graphic - Fill",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Big N 1",
+ "np": 2,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Group 1",
+ "np": 0,
+ "cix": 2,
+ "bm": 0,
+ "ix": 2,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ }
+ ],
+ "ip": 0,
+ "op": 3868,
+ "st": 0,
+ "bm": 0
+ },
+ {
+ "ddd": 0,
+ "ind": 4,
+ "ty": 4,
+ "nm": "Big N 2",
+ "parent": 1,
+ "sr": 1,
+ "ks": {
+ "o": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.667
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.333
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 0,
+ "s": [
+ 0
+ ]
+ },
+ {
+ "i": {
+ "x": [
+ 0.833
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.333
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 10.666,
+ "s": [
+ 100
+ ]
+ },
+ {
+ "i": {
+ "x": [
+ 1
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.612
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 114,
+ "s": [
+ 100
+ ]
+ },
+ {
+ "t": 142,
+ "s": [
+ 0
+ ]
+ }
+ ],
+ "ix": 11
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 10
+ },
+ "p": {
+ "a": 0,
+ "k": [
+ 77.223,
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 77.223,
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100,
+ 100
+ ],
+ "ix": 6
+ }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.252,
+ "y": 1
+ },
+ "o": {
+ "x": 0.434,
+ "y": 0
+ },
+ "t": 0,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 1.198,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -0.901,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 34.099,
+ -359.119
+ ],
+ [
+ 120.288,
+ -359.43
+ ],
+ [
+ 120.49,
+ -359.888
+ ],
+ [
+ 33.164,
+ -359.117
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "i": {
+ "x": 0.833,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0
+ },
+ "t": 24,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 28.673,
+ 0.875
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -28.673,
+ -3.601
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 34.128,
+ -218.21
+ ],
+ [
+ 120.318,
+ -218.521
+ ],
+ [
+ 120.318,
+ 218.521
+ ],
+ [
+ 34.128,
+ 211.337
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "i": {
+ "x": 0.833,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0
+ },
+ "t": 124,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 28.673,
+ 0.875
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -28.673,
+ -3.601
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 34.128,
+ -218.21
+ ],
+ [
+ 120.318,
+ -218.521
+ ],
+ [
+ 120.318,
+ 218.521
+ ],
+ [
+ 34.128,
+ 211.337
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "t": 156,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 28.249,
+ -4.53
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -27.545,
+ 1.34
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 48.414,
+ -218.706
+ ],
+ [
+ 114.365,
+ -217.965
+ ],
+ [
+ 116.869,
+ 194.041
+ ],
+ [
+ 44.408,
+ 201.102
+ ]
+ ],
+ "c": true
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "fl",
+ "c": {
+ "a": 0,
+ "k": [
+ 0.694117647059,
+ 0.023529411765,
+ 0.058823529412,
+ 1
+ ],
+ "ix": 4
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 5
+ },
+ "r": 1,
+ "bm": 0,
+ "nm": "Fill 1",
+ "mn": "ADBE Vector Graphic - Fill",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Big N 2",
+ "np": 2,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ }
+ ],
+ "ip": 0,
+ "op": 3868,
+ "st": 0,
+ "bm": 0
+ },
+ {
+ "ddd": 0,
+ "ind": 5,
+ "ty": 4,
+ "nm": "Big N 3 matte",
+ "parent": 1,
+ "td": 1,
+ "sr": 1,
+ "ks": {
+ "o": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.667
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.333
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 38,
+ "s": [
+ 0
+ ]
+ },
+ {
+ "i": {
+ "x": [
+ 0.833
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.167
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 48.666,
+ "s": [
+ 100
+ ]
+ },
+ {
+ "i": {
+ "x": [
+ 1
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.612
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 114,
+ "s": [
+ 100
+ ]
+ },
+ {
+ "t": 142,
+ "s": [
+ 0
+ ]
+ }
+ ],
+ "ix": 11
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 10
+ },
+ "p": {
+ "a": 0,
+ "k": [
+ -77.223,
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ -77.223,
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100,
+ 100
+ ],
+ "ix": 6
+ }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.252,
+ "y": 1
+ },
+ "o": {
+ "x": 0.434,
+ "y": 0
+ },
+ "t": 38,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 1.089
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 26.294,
+ 0.724
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -34.128,
+ -218.21
+ ],
+ [
+ -120.318,
+ -218.521
+ ],
+ [
+ -120.72,
+ -218.979
+ ],
+ [
+ -34.705,
+ -218.587
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "i": {
+ "x": 0.833,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0
+ },
+ "t": 60,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -28.673,
+ 0.875
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 28.673,
+ -3.601
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -34.128,
+ -218.21
+ ],
+ [
+ -120.318,
+ -218.521
+ ],
+ [
+ -120.318,
+ 218.521
+ ],
+ [
+ -34.128,
+ 211.337
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "i": {
+ "x": 0.833,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0
+ },
+ "t": 124,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -28.673,
+ 0.875
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 28.673,
+ -3.601
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -34.128,
+ -218.21
+ ],
+ [
+ -120.318,
+ -218.521
+ ],
+ [
+ -120.318,
+ 218.521
+ ],
+ [
+ -34.128,
+ 211.337
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "t": 156,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -28.758,
+ -0.959
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 28.673,
+ -3.601
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -43.652,
+ -218.74
+ ],
+ [
+ -106.032,
+ -218.137
+ ],
+ [
+ -106.032,
+ 217.33
+ ],
+ [
+ -37.7,
+ 211.816
+ ]
+ ],
+ "c": true
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "fl",
+ "c": {
+ "a": 0,
+ "k": [
+ 0.694117647059,
+ 0.023529411765,
+ 0.058823529412,
+ 1
+ ],
+ "ix": 4
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 5
+ },
+ "r": 1,
+ "bm": 0,
+ "nm": "Fill 1",
+ "mn": "ADBE Vector Graphic - Fill",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Big N 3",
+ "np": 2,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ }
+ ],
+ "ip": 0,
+ "op": 3868,
+ "st": 0,
+ "bm": 0
+ },
+ {
+ "ddd": 0,
+ "ind": 6,
+ "ty": 4,
+ "nm": "Big N 1 shadow",
+ "tt": 1,
+ "sr": 1,
+ "ks": {
+ "o": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.667
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.333
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 18,
+ "s": [
+ 0
+ ]
+ },
+ {
+ "i": {
+ "x": [
+ 0.833
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.167
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 28.666,
+ "s": [
+ 100
+ ]
+ },
+ {
+ "i": {
+ "x": [
+ 1
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.612
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 114,
+ "s": [
+ 100
+ ]
+ },
+ {
+ "t": 142,
+ "s": [
+ 0
+ ]
+ }
+ ],
+ "ix": 11
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 10
+ },
+ "p": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.455,
+ "y": 1
+ },
+ "o": {
+ "x": 0.684,
+ "y": 0
+ },
+ "t": 104,
+ "s": [
+ 256,
+ 256,
+ 0
+ ],
+ "to": [
+ -24.667,
+ 0,
+ 0
+ ],
+ "ti": [
+ 24.667,
+ 0,
+ 0
+ ]
+ },
+ {
+ "t": 154.74609375,
+ "s": [
+ 108,
+ 256,
+ 0
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0.209,
+ 0.143,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.461,
+ 0.461,
+ 0.667
+ ],
+ "y": [
+ 1,
+ 1,
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.655,
+ 0.655,
+ 0.333
+ ],
+ "y": [
+ 0,
+ 0,
+ 0
+ ]
+ },
+ "t": 46,
+ "s": [
+ 66,
+ 66,
+ 100
+ ]
+ },
+ {
+ "t": 104,
+ "s": [
+ 21,
+ 21,
+ 100
+ ]
+ }
+ ],
+ "ix": 6
+ }
+ },
+ "ao": 0,
+ "ef": [
+ {
+ "ty": 25,
+ "nm": "Drop Shadow",
+ "np": 8,
+ "mn": "ADBE Drop Shadow",
+ "ix": 1,
+ "en": 1,
+ "ef": [
+ {
+ "ty": 2,
+ "nm": "Shadow Color",
+ "mn": "ADBE Drop Shadow-0001",
+ "ix": 1,
+ "v": {
+ "a": 0,
+ "k": [
+ 0.086274512112,
+ 0,
+ 0.0074725952,
+ 1
+ ],
+ "ix": 1
+ }
+ },
+ {
+ "ty": 0,
+ "nm": "Opacity",
+ "mn": "ADBE Drop Shadow-0002",
+ "ix": 2,
+ "v": {
+ "a": 0,
+ "k": 178.5,
+ "ix": 2
+ }
+ },
+ {
+ "ty": 0,
+ "nm": "Direction",
+ "mn": "ADBE Drop Shadow-0003",
+ "ix": 3,
+ "v": {
+ "a": 0,
+ "k": 0,
+ "ix": 3
+ }
+ },
+ {
+ "ty": 0,
+ "nm": "Distance",
+ "mn": "ADBE Drop Shadow-0004",
+ "ix": 4,
+ "v": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ }
+ },
+ {
+ "ty": 0,
+ "nm": "Softness",
+ "mn": "ADBE Drop Shadow-0005",
+ "ix": 5,
+ "v": {
+ "a": 0,
+ "k": 100,
+ "ix": 5
+ }
+ },
+ {
+ "ty": 7,
+ "nm": "Shadow Only",
+ "mn": "ADBE Drop Shadow-0006",
+ "ix": 6,
+ "v": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ }
+ }
+ ]
+ }
+ ],
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.252,
+ "y": 1
+ },
+ "o": {
+ "x": 0.434,
+ "y": 0
+ },
+ "t": 18,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 42.684,
+ 1.078
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 120.607,
+ 218.722
+ ],
+ [
+ 31.805,
+ 211.525
+ ],
+ [
+ 31.977,
+ 211.212
+ ],
+ [
+ 120.318,
+ 218.496
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "i": {
+ "x": 0.833,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0
+ },
+ "t": 46,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 42.684,
+ 1.078
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -34.128,
+ -218.21
+ ],
+ [
+ -119.9,
+ -218.21
+ ],
+ [
+ 31.977,
+ 211.212
+ ],
+ [
+ 120.318,
+ 218.496
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "i": {
+ "x": 0.833,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0
+ },
+ "t": 124,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 42.684,
+ 1.078
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -34.128,
+ -218.21
+ ],
+ [
+ -119.9,
+ -218.21
+ ],
+ [
+ 31.977,
+ 211.212
+ ],
+ [
+ 120.318,
+ 218.496
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "t": 156,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 44.422,
+ -6.307
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -47.223,
+ -218.706
+ ],
+ [
+ -102.043,
+ -218.706
+ ],
+ [
+ 41.501,
+ 198.117
+ ],
+ [
+ 102.46,
+ 192.802
+ ]
+ ],
+ "c": true
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "fl",
+ "c": {
+ "a": 0,
+ "k": [
+ 0.898039215686,
+ 0.035294117647,
+ 0.078431372549,
+ 1
+ ],
+ "ix": 4
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 5
+ },
+ "r": 1,
+ "bm": 0,
+ "nm": "Fill 1",
+ "mn": "ADBE Vector Graphic - Fill",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Big N 1",
+ "np": 2,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ }
+ ],
+ "ip": 0,
+ "op": 3868,
+ "st": 0,
+ "bm": 0
+ },
+ {
+ "ddd": 0,
+ "ind": 7,
+ "ty": 4,
+ "nm": "Big N 3",
+ "parent": 1,
+ "sr": 1,
+ "ks": {
+ "o": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.667
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.333
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 38,
+ "s": [
+ 0
+ ]
+ },
+ {
+ "i": {
+ "x": [
+ 0.833
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.167
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 48.666,
+ "s": [
+ 100
+ ]
+ },
+ {
+ "i": {
+ "x": [
+ 1
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.612
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 114,
+ "s": [
+ 100
+ ]
+ },
+ {
+ "t": 142,
+ "s": [
+ 0
+ ]
+ }
+ ],
+ "ix": 11
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 10
+ },
+ "p": {
+ "a": 0,
+ "k": [
+ -77.223,
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ -77.223,
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100,
+ 100
+ ],
+ "ix": 6
+ }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.252,
+ "y": 1
+ },
+ "o": {
+ "x": 0.434,
+ "y": 0
+ },
+ "t": 38,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 1.089
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 26.294,
+ 0.724
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -34.128,
+ -218.21
+ ],
+ [
+ -120.318,
+ -218.521
+ ],
+ [
+ -120.72,
+ -218.979
+ ],
+ [
+ -34.705,
+ -218.587
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "i": {
+ "x": 0.833,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0
+ },
+ "t": 60,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -28.673,
+ 0.875
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 28.673,
+ -3.601
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -34.128,
+ -218.21
+ ],
+ [
+ -120.318,
+ -218.521
+ ],
+ [
+ -120.318,
+ 218.521
+ ],
+ [
+ -34.128,
+ 211.337
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "i": {
+ "x": 0.833,
+ "y": 1
+ },
+ "o": {
+ "x": 0.167,
+ "y": 0
+ },
+ "t": 124,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -28.673,
+ 0.875
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 28.673,
+ -3.601
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -34.128,
+ -218.21
+ ],
+ [
+ -120.318,
+ -218.521
+ ],
+ [
+ -120.318,
+ 218.521
+ ],
+ [
+ -34.128,
+ 211.337
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "t": 156,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -28.758,
+ -0.959
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 28.673,
+ -3.601
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -43.652,
+ -218.74
+ ],
+ [
+ -106.032,
+ -218.137
+ ],
+ [
+ -106.032,
+ 217.33
+ ],
+ [
+ -37.7,
+ 211.816
+ ]
+ ],
+ "c": true
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "fl",
+ "c": {
+ "a": 0,
+ "k": [
+ 0.694117647059,
+ 0.023529411765,
+ 0.058823529412,
+ 1
+ ],
+ "ix": 4
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 5
+ },
+ "r": 1,
+ "bm": 0,
+ "nm": "Fill 1",
+ "mn": "ADBE Vector Graphic - Fill",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Big N 3",
+ "np": 2,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ }
+ ],
+ "ip": 0,
+ "op": 3868,
+ "st": 0,
+ "bm": 0
+ },
+ {
+ "ddd": 0,
+ "ind": 8,
+ "ty": 4,
+ "nm": "Netflix reveal",
+ "parent": 9,
+ "td": 1,
+ "sr": 1,
+ "ks": {
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 11
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 10
+ },
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100,
+ 100
+ ],
+ "ix": 6
+ }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.715,
+ "y": 1
+ },
+ "o": {
+ "x": 0.414,
+ "y": 0
+ },
+ "t": 206.207,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 166,
+ -55
+ ],
+ [
+ 165,
+ -52
+ ]
+ ],
+ "c": false
+ }
+ ]
+ },
+ {
+ "t": 220,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 164,
+ -51
+ ],
+ [
+ 125,
+ 45.5
+ ]
+ ],
+ "c": false
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 20,
+ "ix": 5
+ },
+ "lc": 1,
+ "lj": 1,
+ "ml": 4,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 2",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.715,
+ "y": 1
+ },
+ "o": {
+ "x": 0.414,
+ "y": 0
+ },
+ "t": 200.297,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 125,
+ -54.5
+ ],
+ [
+ 125,
+ -52
+ ]
+ ],
+ "c": false
+ }
+ ]
+ },
+ {
+ "t": 214.08984375,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 126.5,
+ -52
+ ],
+ [
+ 164,
+ 50
+ ]
+ ],
+ "c": false
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 20,
+ "ix": 5
+ },
+ "lc": 1,
+ "lj": 1,
+ "ml": 4,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 2,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 144.5,
+ -1
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 144.5,
+ -1
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "X",
+ "np": 2,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.715,
+ "y": 1
+ },
+ "o": {
+ "x": 0.414,
+ "y": 0
+ },
+ "t": 186.271,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 100,
+ -51
+ ],
+ [
+ 100,
+ -48
+ ]
+ ],
+ "c": false
+ }
+ ]
+ },
+ {
+ "t": 198.09375,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 100,
+ -47
+ ],
+ [
+ 100,
+ 42
+ ]
+ ],
+ "c": false
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 20,
+ "ix": 5
+ },
+ "lc": 1,
+ "lj": 1,
+ "ml": 4,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "I",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 2,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.715,
+ "y": 1
+ },
+ "o": {
+ "x": 0.414,
+ "y": 0
+ },
+ "t": 175.586,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 37,
+ 29
+ ],
+ [
+ 40.5,
+ 29
+ ]
+ ],
+ "c": false
+ }
+ ]
+ },
+ {
+ "t": 189.37890625,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 37,
+ 29
+ ],
+ [
+ 83.5,
+ 28.5
+ ]
+ ],
+ "c": false
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 20,
+ "ix": 5
+ },
+ "lc": 1,
+ "lj": 1,
+ "ml": 4,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "L 2",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.715,
+ "y": 1
+ },
+ "o": {
+ "x": 0.414,
+ "y": 0
+ },
+ "t": 171.645,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 49,
+ -50.5
+ ],
+ [
+ 49,
+ -48.5
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "t": 185.4375,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 49,
+ -47.5
+ ],
+ [
+ 49.5,
+ 38
+ ]
+ ],
+ "c": false
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 20,
+ "ix": 5
+ },
+ "lc": 1,
+ "lj": 1,
+ "ml": 4,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "L1",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 2,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 60.25,
+ -4.75
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 60.25,
+ -4.75
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "L",
+ "np": 2,
+ "cix": 2,
+ "bm": 0,
+ "ix": 3,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.715,
+ "y": 1
+ },
+ "o": {
+ "x": 0.414,
+ "y": 0
+ },
+ "t": 159.992,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -9.5,
+ -7.5
+ ],
+ [
+ -11.5,
+ -7.5
+ ]
+ ],
+ "c": false
+ }
+ ]
+ },
+ {
+ "t": 175.75390625,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 28,
+ -7.5
+ ],
+ [
+ -9.5,
+ -7.5
+ ]
+ ],
+ "c": false
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 20,
+ "ix": 5
+ },
+ "lc": 1,
+ "lj": 1,
+ "ml": 4,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 2",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.715,
+ "y": 1
+ },
+ "o": {
+ "x": 0.414,
+ "y": 0
+ },
+ "t": 154.08,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 0.5,
+ -50
+ ],
+ [
+ 0.5,
+ -48
+ ]
+ ],
+ "c": false
+ }
+ ]
+ },
+ {
+ "t": 169.84375,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 0.5,
+ -48
+ ],
+ [
+ 0,
+ 37
+ ]
+ ],
+ "c": false
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 20,
+ "ix": 5
+ },
+ "lc": 1,
+ "lj": 1,
+ "ml": 4,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 3",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 2,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.715,
+ "y": 1
+ },
+ "o": {
+ "x": 0.414,
+ "y": 0
+ },
+ "t": 145.266,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -10.5,
+ -39.5
+ ],
+ [
+ -12,
+ -39.5
+ ]
+ ],
+ "c": false
+ }
+ ]
+ },
+ {
+ "t": 160.693359375,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 36,
+ -39.5
+ ],
+ [
+ -9,
+ -39.5
+ ]
+ ],
+ "c": false
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 20,
+ "ix": 5
+ },
+ "lc": 1,
+ "lj": 1,
+ "ml": 4,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 3,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 13.25,
+ -5.5
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 13.25,
+ -5.5
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "F",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 4,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.715,
+ "y": 1
+ },
+ "o": {
+ "x": 0.414,
+ "y": 0
+ },
+ "t": 136.115,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -40.5,
+ -54
+ ],
+ [
+ -40.5,
+ -49.5
+ ]
+ ],
+ "c": false
+ }
+ ]
+ },
+ {
+ "t": 151.876953125,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -38.5,
+ -45.5
+ ],
+ [
+ -39,
+ 38.5
+ ]
+ ],
+ "c": false
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 20,
+ "ix": 5
+ },
+ "lc": 1,
+ "lj": 1,
+ "ml": 4,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 2",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.715,
+ "y": 1
+ },
+ "o": {
+ "x": 0.414,
+ "y": 0
+ },
+ "t": 132.174,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -62.5,
+ -38.5
+ ],
+ [
+ -66,
+ -38.5
+ ]
+ ],
+ "c": false
+ }
+ ]
+ },
+ {
+ "t": 147.9375,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -14.5,
+ -40.5
+ ],
+ [
+ -63.5,
+ -38.5
+ ]
+ ],
+ "c": false
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 20,
+ "ix": 5
+ },
+ "lc": 1,
+ "lj": 1,
+ "ml": 4,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 2,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ -39,
+ -3.5
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ -39,
+ -3.5
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "T",
+ "np": 2,
+ "cix": 2,
+ "bm": 0,
+ "ix": 5,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.715,
+ "y": 1
+ },
+ "o": {
+ "x": 0.414,
+ "y": 0
+ },
+ "t": 127.73,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -114,
+ 32.5
+ ],
+ [
+ -119,
+ 32.5
+ ]
+ ],
+ "c": false
+ }
+ ]
+ },
+ {
+ "t": 147.435546875,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -67.5,
+ 29
+ ],
+ [
+ -112,
+ 32.5
+ ]
+ ],
+ "c": false
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 20,
+ "ix": 5
+ },
+ "lc": 1,
+ "lj": 1,
+ "ml": 4,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 3",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.715,
+ "y": 1
+ },
+ "o": {
+ "x": 0.414,
+ "y": 0
+ },
+ "t": 121.82,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -115,
+ -6.5
+ ],
+ [
+ -119.5,
+ -6.5
+ ]
+ ],
+ "c": true
+ }
+ ]
+ },
+ {
+ "t": 141.033203125,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -74.5,
+ -6
+ ],
+ [
+ -113,
+ -6
+ ]
+ ],
+ "c": true
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 20,
+ "ix": 5
+ },
+ "lc": 1,
+ "lj": 1,
+ "ml": 4,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 2",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 2,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.715,
+ "y": 1
+ },
+ "o": {
+ "x": 0.414,
+ "y": 0
+ },
+ "t": 117.881,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -103.5,
+ -54.5
+ ],
+ [
+ -103.5,
+ -49
+ ]
+ ],
+ "c": false
+ }
+ ]
+ },
+ {
+ "t": 137.58203125,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -103.5,
+ -48.5
+ ],
+ [
+ -102.5,
+ 42
+ ]
+ ],
+ "c": false
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 20,
+ "ix": 5
+ },
+ "lc": 1,
+ "lj": 1,
+ "ml": 4,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 4",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 3,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": 0.715,
+ "y": 1
+ },
+ "o": {
+ "x": 0.414,
+ "y": 0
+ },
+ "t": 110,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -117,
+ -38
+ ],
+ [
+ -120.5,
+ -38
+ ]
+ ],
+ "c": false
+ }
+ ]
+ },
+ {
+ "t": 129.2109375,
+ "s": [
+ {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -68,
+ -38
+ ],
+ [
+ -114.5,
+ -38
+ ]
+ ],
+ "c": false
+ }
+ ]
+ }
+ ],
+ "ix": 2
+ },
+ "nm": "Path 1",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "st",
+ "c": {
+ "a": 0,
+ "k": [
+ 1,
+ 1,
+ 1,
+ 1
+ ],
+ "ix": 3
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 4
+ },
+ "w": {
+ "a": 0,
+ "k": 20,
+ "ix": 5
+ },
+ "lc": 1,
+ "lj": 1,
+ "ml": 4,
+ "bm": 0,
+ "nm": "Stroke 1",
+ "mn": "ADBE Vector Graphic - Stroke",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Shape 1",
+ "np": 3,
+ "cix": 2,
+ "bm": 0,
+ "ix": 4,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ -90,
+ -3.25
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ -90,
+ -3.25
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "E",
+ "np": 4,
+ "cix": 2,
+ "bm": 0,
+ "ix": 6,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ }
+ ],
+ "ip": 101,
+ "op": 3868,
+ "st": 0,
+ "bm": 0
+ },
+ {
+ "ddd": 0,
+ "ind": 9,
+ "ty": 4,
+ "nm": "Etflix",
+ "tt": 1,
+ "sr": 1,
+ "ks": {
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 11
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 10
+ },
+ "p": {
+ "s": true,
+ "x": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.455
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.684
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 104,
+ "s": [
+ 402.75
+ ]
+ },
+ {
+ "t": 154.74609375,
+ "s": [
+ 256
+ ]
+ }
+ ],
+ "ix": 3
+ },
+ "y": {
+ "a": 0,
+ "k": 256,
+ "ix": 4
+ }
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100,
+ 100
+ ],
+ "ix": 6
+ }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 1,
+ "ty": "sh",
+ "ix": 2,
+ "ks": {
+ "a": 0,
+ "k": {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -5.131,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 5.401,
+ -0.27
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -8.551,
+ 0.27
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 5.582,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -6.392,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 8.462,
+ -0.54
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -95.285,
+ -12.333
+ ],
+ [
+ -76.021,
+ -12.603
+ ],
+ [
+ -76.021,
+ 1.8
+ ],
+ [
+ -95.285,
+ 2.07
+ ],
+ [
+ -95.285,
+ 23.495
+ ],
+ [
+ -69.81,
+ 21.964
+ ],
+ [
+ -69.81,
+ 35.826
+ ],
+ [
+ -109.689,
+ 38.978
+ ],
+ [
+ -109.689,
+ -46.09
+ ],
+ [
+ -69.81,
+ -46.09
+ ],
+ [
+ -69.81,
+ -31.687
+ ],
+ [
+ -95.285,
+ -31.687
+ ]
+ ],
+ "c": true
+ },
+ "ix": 2
+ },
+ "nm": "Path 2",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ind": 2,
+ "ty": "sh",
+ "ix": 3,
+ "ks": {
+ "a": 0,
+ "k": {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 4.68,
+ -0.18
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -4.861,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -16.249,
+ -31.686
+ ],
+ [
+ -31.192,
+ -31.686
+ ],
+ [
+ -31.192,
+ 34.568
+ ],
+ [
+ -45.594,
+ 34.747
+ ],
+ [
+ -45.594,
+ -31.686
+ ],
+ [
+ -60.537,
+ -31.686
+ ],
+ [
+ -60.537,
+ -46.09
+ ],
+ [
+ -16.248,
+ -46.09
+ ]
+ ],
+ "c": true
+ },
+ "ix": 2
+ },
+ "nm": "Path 3",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ind": 3,
+ "ty": "sh",
+ "ix": 4,
+ "ks": {
+ "a": 0,
+ "k": {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 7.156,
+ -13.323
+ ],
+ [
+ 26.871,
+ -13.323
+ ],
+ [
+ 26.871,
+ 1.08
+ ],
+ [
+ 7.156,
+ 1.08
+ ],
+ [
+ 7.156,
+ 33.757
+ ],
+ [
+ -6.978,
+ 33.757
+ ],
+ [
+ -6.978,
+ -46.09
+ ],
+ [
+ 33.262,
+ -46.09
+ ],
+ [
+ 33.262,
+ -31.687
+ ],
+ [
+ 7.156,
+ -31.687
+ ]
+ ],
+ "c": true
+ },
+ "ix": 2
+ },
+ "nm": "Path 4",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ind": 4,
+ "ty": "sh",
+ "ix": 5,
+ "ks": {
+ "a": 0,
+ "k": {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -8.012,
+ -0.449
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 13.143,
+ 0.271
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 8.192,
+ 0.18
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -12.873,
+ -0.811
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 56.667,
+ 21.154
+ ],
+ [
+ 81.152,
+ 22.415
+ ],
+ [
+ 81.152,
+ 36.638
+ ],
+ [
+ 42.264,
+ 34.747
+ ],
+ [
+ 42.264,
+ -46.09
+ ],
+ [
+ 56.667,
+ -46.09
+ ]
+ ],
+ "c": true
+ },
+ "ix": 2
+ },
+ "nm": "Path 5",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ind": 5,
+ "ty": "sh",
+ "ix": 6,
+ "ks": {
+ "a": 0,
+ "k": {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ -4.681,
+ -0.539
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 4.591,
+ 0.27
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 93.304,
+ 37.628
+ ],
+ [
+ 107.437,
+ 38.708
+ ],
+ [
+ 107.437,
+ -46.09
+ ],
+ [
+ 93.304,
+ -46.09
+ ]
+ ],
+ "c": true
+ },
+ "ix": 2
+ },
+ "nm": "Path 6",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ind": 6,
+ "ty": "sh",
+ "ix": 7,
+ "ks": {
+ "a": 0,
+ "k": {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 5.401,
+ 0.9
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 5.22,
+ 0.72
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -5.403,
+ -0.72
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -5.222,
+ -0.901
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ 170.541,
+ -46.09
+ ],
+ [
+ 152.267,
+ -2.25
+ ],
+ [
+ 170.541,
+ 46.09
+ ],
+ [
+ 154.337,
+ 43.479
+ ],
+ [
+ 143.985,
+ 16.834
+ ],
+ [
+ 133.454,
+ 41.319
+ ],
+ [
+ 117.971,
+ 39.428
+ ],
+ [
+ 136.515,
+ -2.791
+ ],
+ [
+ 119.771,
+ -46.09
+ ],
+ [
+ 135.253,
+ -46.09
+ ],
+ [
+ 144.705,
+ -21.875
+ ],
+ [
+ 154.788,
+ -46.09
+ ]
+ ],
+ "c": true
+ },
+ "ix": 2
+ },
+ "nm": "Path 7",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "fl",
+ "c": {
+ "a": 0,
+ "k": [
+ 0.898039215686,
+ 0.035294117647,
+ 0.078431372549,
+ 1
+ ],
+ "ix": 4
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 5
+ },
+ "r": 1,
+ "bm": 0,
+ "nm": "Fill 1",
+ "mn": "ADBE Vector Graphic - Fill",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Netflix Wordmark",
+ "np": 8,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ }
+ ],
+ "ip": 102,
+ "op": 3868,
+ "st": 0,
+ "bm": 0
+ },
+ {
+ "ddd": 0,
+ "ind": 10,
+ "ty": 4,
+ "nm": "Netflix N",
+ "sr": 1,
+ "ks": {
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 11
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 10
+ },
+ "p": {
+ "s": true,
+ "x": {
+ "a": 1,
+ "k": [
+ {
+ "i": {
+ "x": [
+ 0.455
+ ],
+ "y": [
+ 1
+ ]
+ },
+ "o": {
+ "x": [
+ 0.684
+ ],
+ "y": [
+ 0
+ ]
+ },
+ "t": 104,
+ "s": [
+ 402.75
+ ]
+ },
+ {
+ "t": 154.74609375,
+ "s": [
+ 256
+ ]
+ }
+ ],
+ "ix": 3
+ },
+ "y": {
+ "a": 0,
+ "k": 256,
+ "ix": 4
+ }
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100,
+ 100
+ ],
+ "ix": 6
+ }
+ },
+ "ao": 0,
+ "shapes": [
+ {
+ "ty": "gr",
+ "it": [
+ {
+ "ind": 0,
+ "ty": "sh",
+ "ix": 1,
+ "ks": {
+ "a": 0,
+ "k": {
+ "i": [
+ [
+ 0,
+ 0
+ ],
+ [
+ 5.401,
+ -0.719
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 4.861,
+ -0.72
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "o": [
+ [
+ -5.131,
+ 0.901
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ -5.131,
+ 0.54
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ],
+ [
+ 0,
+ 0
+ ]
+ ],
+ "v": [
+ [
+ -123.641,
+ 40.148
+ ],
+ [
+ -139.394,
+ 42.039
+ ],
+ [
+ -155.868,
+ -6.211
+ ],
+ [
+ -155.868,
+ 44.11
+ ],
+ [
+ -170.541,
+ 46.09
+ ],
+ [
+ -170.541,
+ -46.09
+ ],
+ [
+ -156.858,
+ -46.09
+ ],
+ [
+ -138.134,
+ 6.212
+ ],
+ [
+ -138.134,
+ -46.09
+ ],
+ [
+ -123.641,
+ -46.09
+ ]
+ ],
+ "c": true
+ },
+ "ix": 2
+ },
+ "nm": "N",
+ "mn": "ADBE Vector Shape - Group",
+ "hd": false
+ },
+ {
+ "ty": "fl",
+ "c": {
+ "a": 0,
+ "k": [
+ 0.898039215686,
+ 0.035294117647,
+ 0.078431372549,
+ 1
+ ],
+ "ix": 4
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 5
+ },
+ "r": 1,
+ "bm": 0,
+ "nm": "Fill 1",
+ "mn": "ADBE Vector Graphic - Fill",
+ "hd": false
+ },
+ {
+ "ty": "tr",
+ "p": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 2
+ },
+ "a": {
+ "a": 0,
+ "k": [
+ 0,
+ 0
+ ],
+ "ix": 1
+ },
+ "s": {
+ "a": 0,
+ "k": [
+ 100,
+ 100
+ ],
+ "ix": 3
+ },
+ "r": {
+ "a": 0,
+ "k": 0,
+ "ix": 6
+ },
+ "o": {
+ "a": 0,
+ "k": 100,
+ "ix": 7
+ },
+ "sk": {
+ "a": 0,
+ "k": 0,
+ "ix": 4
+ },
+ "sa": {
+ "a": 0,
+ "k": 0,
+ "ix": 5
+ },
+ "nm": "Transform"
+ }
+ ],
+ "nm": "Netflix Wordmark",
+ "np": 2,
+ "cix": 2,
+ "bm": 0,
+ "ix": 1,
+ "mn": "ADBE Vector Group",
+ "hd": false
+ }
+ ],
+ "ip": 102,
+ "op": 3868,
+ "st": 0,
+ "bm": 0
+ }
+ ],
+ "markers": []
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/codandotv/streamplayerapp/MainActivity.kt b/composeApp/src/commonMain/kotlin/com.codandotv.streamplayerapp/StreamPlayerApp.kt
similarity index 58%
rename from app/src/main/java/com/codandotv/streamplayerapp/MainActivity.kt
rename to composeApp/src/commonMain/kotlin/com.codandotv.streamplayerapp/StreamPlayerApp.kt
index 94deedd3..98362c68 100644
--- a/app/src/main/java/com/codandotv/streamplayerapp/MainActivity.kt
+++ b/composeApp/src/commonMain/kotlin/com.codandotv.streamplayerapp/StreamPlayerApp.kt
@@ -1,22 +1,10 @@
package com.codandotv.streamplayerapp
-import android.os.Bundle
-import androidx.activity.ComponentActivity
-import androidx.activity.compose.setContent
import androidx.compose.runtime.Composable
import androidx.navigation.compose.rememberNavController
import com.codandotv.streamplayerapp.core_shared_ui.theme.StreamPlayerTheme
import com.codandotv.streamplayerapp.navigation.NavigationGraph
-class MainActivity : ComponentActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContent {
- StreamPlayerApp()
- }
- }
-}
-
@Composable
fun StreamPlayerApp() {
StreamPlayerTheme {
diff --git a/app/src/main/java/com/codandotv/streamplayerapp/di/AppModule.kt b/composeApp/src/commonMain/kotlin/com.codandotv.streamplayerapp/di/AppModule.kt
similarity index 78%
rename from app/src/main/java/com/codandotv/streamplayerapp/di/AppModule.kt
rename to composeApp/src/commonMain/kotlin/com.codandotv.streamplayerapp/di/AppModule.kt
index 6fcc0006..d904287c 100644
--- a/app/src/main/java/com/codandotv/streamplayerapp/di/AppModule.kt
+++ b/composeApp/src/commonMain/kotlin/com.codandotv.streamplayerapp/di/AppModule.kt
@@ -1,16 +1,15 @@
package com.codandotv.streamplayerapp.di
-import android.content.res.Resources
import com.codandotv.streamplayerapp.core_local_storage.di.LocalStorageModule
import com.codandotv.streamplayerapp.core_networking.di.NetworkModule
import com.codandotv.streamplayerapp.core_shared.qualifier.QualifierDispatcherIO
import kotlinx.coroutines.Dispatchers
-import org.koin.android.ext.koin.androidContext
+import kotlinx.coroutines.IO
import org.koin.dsl.module
object AppModule {
private val module = module {
- single { androidContext().resources }
+// single { androidContext().resources }
single(QualifierDispatcherIO) { Dispatchers.IO }
}
val list = module + NetworkModule.module + LocalStorageModule.module
diff --git a/app/src/main/java/com/codandotv/streamplayerapp/navigation/NavigationGraph.kt b/composeApp/src/commonMain/kotlin/com.codandotv.streamplayerapp/navigation/NavigationGraph.kt
similarity index 75%
rename from app/src/main/java/com/codandotv/streamplayerapp/navigation/NavigationGraph.kt
rename to composeApp/src/commonMain/kotlin/com.codandotv.streamplayerapp/navigation/NavigationGraph.kt
index b8df253a..63251780 100644
--- a/app/src/main/java/com/codandotv/streamplayerapp/navigation/NavigationGraph.kt
+++ b/composeApp/src/commonMain/kotlin/com.codandotv.streamplayerapp/navigation/NavigationGraph.kt
@@ -1,7 +1,5 @@
package com.codandotv.streamplayerapp.navigation
-import android.annotation.SuppressLint
-import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -14,11 +12,12 @@ import androidx.navigation.compose.composable
import com.codandotv.streamplayerapp.core_navigation.bottomnavigation.StreamPlayerBottomNavigation
import com.codandotv.streamplayerapp.core_navigation.routes.BottomNavRoutes
import com.codandotv.streamplayerapp.core_navigation.routes.Routes
-import com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.navigation.detailStreamNavGraph
import com.codandotv.streamplayerapp.feature_list_streams.list.presentation.navigation.listStreamsNavGraph
-import com.codandotv.streamplayerapp.feature_list_streams.search.presentation.navigation.searchStreamsNavGraph
-import com.codandotv.streamplayerapp.feature_profile.profile.presentation.navigation.profilePickerStreamNavGraph
-import com.codandotv.streamplayerapp.splah.presentation.navigation.splashNavGraph
+import com.codandotv.streamplayerapp.profile.presentation.navigation.profilePickerStreamNavGraph
+
+import com.codandotv.streamplayerapp.presentation.navigation.splashNavGraph
+import com.codandotv.streamplayerapp.feature_detail.presentation.navigation.detailStreamNavGraph
+import com.codandotv.streamplayerapp.feature_search.presentation.navigation.searchStreamsNavGraph
@Composable
fun NavigationGraph(navController: NavHostController) {
@@ -27,11 +26,11 @@ fun NavigationGraph(navController: NavHostController) {
listStreamsNavGraph(navController = navController)
searchStreamsNavGraph(navController = navController)
detailStreamNavGraph(navController = navController)
+ profilePickerStreamNavGraph(navController = navController)
temporaryFun(BottomNavRoutes.GAMES, navController)
temporaryFun(BottomNavRoutes.NEWS, navController)
temporaryFun(BottomNavRoutes.SCENES, navController)
temporaryFun(BottomNavRoutes.DOWNLOADS, navController)
- profilePickerStreamNavGraph(navController = navController)
}
}
@@ -41,8 +40,6 @@ fun NavGraphBuilder.temporaryFun(route: String, navController: NavController) {
}
}
-@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
-@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun example(navController: NavController, route: String) {
Scaffold(
diff --git a/composeApp/src/commonMain/kotlin/com.codandotv.streamplayerapp/presentation/components/LottieComponentPlatform.kt b/composeApp/src/commonMain/kotlin/com.codandotv.streamplayerapp/presentation/components/LottieComponentPlatform.kt
new file mode 100644
index 00000000..56f103ff
--- /dev/null
+++ b/composeApp/src/commonMain/kotlin/com.codandotv.streamplayerapp/presentation/components/LottieComponentPlatform.kt
@@ -0,0 +1,11 @@
+package com.codandotv.streamplayerapp.presentation.components
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+
+@Composable
+expect fun LottieComponent(
+ jsonString: String,
+ modifier: Modifier = Modifier,
+ onAnimationFinished: () -> Unit
+)
\ No newline at end of file
diff --git a/app/src/main/java/com/codandotv/streamplayerapp/splah/presentation/navigation/SplashNavigation.kt b/composeApp/src/commonMain/kotlin/com.codandotv.streamplayerapp/presentation/navigation/SplashNavigation.kt
similarity index 77%
rename from app/src/main/java/com/codandotv/streamplayerapp/splah/presentation/navigation/SplashNavigation.kt
rename to composeApp/src/commonMain/kotlin/com.codandotv.streamplayerapp/presentation/navigation/SplashNavigation.kt
index a272c263..9952dc97 100644
--- a/app/src/main/java/com/codandotv/streamplayerapp/splah/presentation/navigation/SplashNavigation.kt
+++ b/composeApp/src/commonMain/kotlin/com.codandotv.streamplayerapp/presentation/navigation/SplashNavigation.kt
@@ -1,11 +1,11 @@
-package com.codandotv.streamplayerapp.splah.presentation.navigation
+package com.codandotv.streamplayerapp.presentation.navigation
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.compose.composable
import com.codandotv.streamplayerapp.core_navigation.routes.BottomNavRoutes
import com.codandotv.streamplayerapp.core_navigation.routes.Routes
-import com.codandotv.streamplayerapp.splah.presentation.screens.SplashScreen
+import com.codandotv.streamplayerapp.presentation.screens.SplashScreen
fun NavGraphBuilder.splashNavGraph(navController: NavHostController) {
composable(Routes.Splash) {
diff --git a/composeApp/src/commonMain/kotlin/com.codandotv.streamplayerapp/presentation/screens/SplashScreen.kt b/composeApp/src/commonMain/kotlin/com.codandotv.streamplayerapp/presentation/screens/SplashScreen.kt
new file mode 100644
index 00000000..ab8cc565
--- /dev/null
+++ b/composeApp/src/commonMain/kotlin/com.codandotv.streamplayerapp/presentation/screens/SplashScreen.kt
@@ -0,0 +1,55 @@
+package com.codandotv.streamplayerapp.presentation.screens
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import com.codandotv.streamplayerapp.presentation.components.LottieComponent
+import org.jetbrains.compose.resources.ExperimentalResourceApi
+import streamplayerapp_kmp.composeapp.generated.resources.Res
+
+@OptIn(ExperimentalResourceApi::class)
+@Composable
+fun SplashScreen(
+ onAnimationFinished: () -> Unit
+) {
+ var lottieAnimationString: String? by remember {
+ mutableStateOf(null)
+ }
+ LaunchedEffect(Unit) {
+ lottieAnimationString = Res.readBytes(
+ "files/lottie/logo.json"
+ ).decodeToString()
+ }
+ Column(
+ modifier = Modifier.fillMaxSize()
+ ) {
+ Box(
+ contentAlignment = Alignment.Center,
+ modifier = Modifier
+ .fillMaxSize()
+ .background(Color.Black)
+ ) {
+ lottieAnimationString?.let {
+ LottieComponent(
+ jsonString = it,
+ modifier = Modifier
+ .fillMaxWidth()
+ .fillMaxHeight(),
+ onAnimationFinished = onAnimationFinished
+ )
+ }
+ }
+ }
+}
diff --git a/composeApp/src/iosMain/kotlin/com.codandotv.streamplayerapp/MainViewController.kt b/composeApp/src/iosMain/kotlin/com.codandotv.streamplayerapp/MainViewController.kt
new file mode 100644
index 00000000..2332ac68
--- /dev/null
+++ b/composeApp/src/iosMain/kotlin/com.codandotv.streamplayerapp/MainViewController.kt
@@ -0,0 +1,7 @@
+package com.codandotv.streamplayerapp
+
+import androidx.compose.ui.window.ComposeUIViewController
+
+fun MainViewController() = ComposeUIViewController {
+ StreamPlayerApp()
+}
\ No newline at end of file
diff --git a/composeApp/src/iosMain/kotlin/com.codandotv.streamplayerapp/di/KoinIosHelper.kt b/composeApp/src/iosMain/kotlin/com.codandotv.streamplayerapp/di/KoinIosHelper.kt
new file mode 100644
index 00000000..bd8d968c
--- /dev/null
+++ b/composeApp/src/iosMain/kotlin/com.codandotv.streamplayerapp/di/KoinIosHelper.kt
@@ -0,0 +1,17 @@
+package com.codandotv.streamplayerapp.di
+
+import com.codandotv.streamplayerapp.presentation.components.LottieViewProvider
+import org.koin.core.context.startKoin
+import org.koin.dsl.module
+
+class KoinIosHelper {
+ fun initKoin(lottieViewProvider: LottieViewProvider) {
+ startKoin {
+ modules(AppModule.list + module {
+ single {
+ lottieViewProvider
+ }
+ })
+ }
+ }
+}
\ No newline at end of file
diff --git a/composeApp/src/iosMain/kotlin/com.codandotv.streamplayerapp/presentation/components/LottieComponentPlatform.ios.kt b/composeApp/src/iosMain/kotlin/com.codandotv.streamplayerapp/presentation/components/LottieComponentPlatform.ios.kt
new file mode 100644
index 00000000..9ed08746
--- /dev/null
+++ b/composeApp/src/iosMain/kotlin/com.codandotv.streamplayerapp/presentation/components/LottieComponentPlatform.ios.kt
@@ -0,0 +1,26 @@
+package com.codandotv.streamplayerapp.presentation.components
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.viewinterop.UIKitView
+import org.koin.mp.KoinPlatform
+import platform.UIKit.UIColor
+import platform.UIKit.UIView
+
+@Composable
+actual fun LottieComponent(
+ jsonString: String,
+ modifier: Modifier,
+ onAnimationFinished: () -> Unit
+) {
+ val provider = KoinPlatform.getKoin().get()
+
+ UIKitView(
+ modifier = modifier,
+ factory = {
+ val view = provider.provideLottieView(jsonString,onAnimationFinished)
+ view.backgroundColor = UIColor.blackColor()
+ view
+ }
+ )
+}
\ No newline at end of file
diff --git a/composeApp/src/iosMain/kotlin/com.codandotv.streamplayerapp/presentation/components/LottieViewProvider.kt b/composeApp/src/iosMain/kotlin/com.codandotv.streamplayerapp/presentation/components/LottieViewProvider.kt
new file mode 100644
index 00000000..f1bf123d
--- /dev/null
+++ b/composeApp/src/iosMain/kotlin/com.codandotv.streamplayerapp/presentation/components/LottieViewProvider.kt
@@ -0,0 +1,7 @@
+package com.codandotv.streamplayerapp.presentation.components
+
+import platform.UIKit.UIView
+
+interface LottieViewProvider {
+ fun provideLottieView(lottieAnimationJson: String, onAnimationFinish : () -> Unit) : UIView
+}
\ No newline at end of file
diff --git a/core-local-storage/build.gradle.kts b/core-local-storage/build.gradle.kts
index c8e2ff05..408d1805 100644
--- a/core-local-storage/build.gradle.kts
+++ b/core-local-storage/build.gradle.kts
@@ -1,13 +1,27 @@
plugins {
- id("com.streamplayer.android-library")
+ id("com.streamplayer.kmp-library")
id("com.google.devtools.ksp")
+ alias(libs.plugins.room)
+}
+
+kotlin {
+ sourceSets {
+ commonMain.dependencies {
+ implementation(libs.room.bundled)
+ implementation(libs.room.runtime)
+
+ implementation(libs.koin.core)
+ }
+ }
}
dependencies {
+ add("kspAndroid", libs.room.compiler)
+ add("kspIosSimulatorArm64", libs.room.compiler)
+ add("kspIosX64", libs.room.compiler)
+ add("kspIosArm64", libs.room.compiler)
+}
- ksp(libs.roomCompiler)
- implementation(libs.bundles.room)
- implementation(libs.bundles.kotlin)
- implementation(libs.bundles.koin)
- testImplementation(libs.bundles.test)
-}
\ No newline at end of file
+room {
+ schemaDirectory("$projectDir/schemas")
+}
diff --git a/core-local-storage/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_local_storage/data/database/AppDatabasePlatform.android.kt b/core-local-storage/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_local_storage/data/database/AppDatabasePlatform.android.kt
new file mode 100644
index 00000000..8540c5f0
--- /dev/null
+++ b/core-local-storage/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_local_storage/data/database/AppDatabasePlatform.android.kt
@@ -0,0 +1,12 @@
+package com.codandotv.streamplayerapp.core_local_storage.data.database
+
+import androidx.room.Room
+import org.koin.mp.KoinPlatform
+
+actual fun databaseInstance(): AppDatabase {
+ return Room.databaseBuilder(
+ KoinPlatform.getKoin().get(),
+ AppDatabase::class.java,
+ dbFileName
+ ).build()
+}
\ No newline at end of file
diff --git a/core-local-storage/src/main/java/com/codandotv/streamplayerapp/core_local_storage/data/dao/FavoriteDao.kt b/core-local-storage/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_local_storage/data/dao/FavoriteDao.kt
similarity index 100%
rename from core-local-storage/src/main/java/com/codandotv/streamplayerapp/core_local_storage/data/dao/FavoriteDao.kt
rename to core-local-storage/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_local_storage/data/dao/FavoriteDao.kt
diff --git a/core-local-storage/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_local_storage/data/database/AppDatabasePlatform.kt b/core-local-storage/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_local_storage/data/database/AppDatabasePlatform.kt
new file mode 100644
index 00000000..64f0a620
--- /dev/null
+++ b/core-local-storage/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_local_storage/data/database/AppDatabasePlatform.kt
@@ -0,0 +1,25 @@
+package com.codandotv.streamplayerapp.core_local_storage.data.database
+
+import androidx.room.ConstructedBy
+import androidx.room.Database
+import androidx.room.RoomDatabase
+import androidx.room.RoomDatabaseConstructor
+import com.codandotv.streamplayerapp.core_local_storage.data.dao.FavoriteDao
+import com.codandotv.streamplayerapp.core_local_storage.domain.model.MovieEntity
+
+
+@Database(entities = [MovieEntity::class], version = 1, exportSchema = false)
+@ConstructedBy(AppDatabaseConstructor::class)
+abstract class AppDatabase : RoomDatabase() {
+ abstract fun favoriteDao(): FavoriteDao
+}
+
+// The Room compiler generates the `actual` implementations.
+@Suppress("NO_ACTUAL_FOR_EXPECT")
+expect object AppDatabaseConstructor : RoomDatabaseConstructor {
+ override fun initialize(): AppDatabase
+}
+
+expect fun databaseInstance(): AppDatabase
+
+internal const val dbFileName = "app-database.db"
\ No newline at end of file
diff --git a/core-local-storage/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_local_storage/di/LocalStorageModule.kt b/core-local-storage/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_local_storage/di/LocalStorageModule.kt
new file mode 100644
index 00000000..9d934c0d
--- /dev/null
+++ b/core-local-storage/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_local_storage/di/LocalStorageModule.kt
@@ -0,0 +1,12 @@
+package com.codandotv.streamplayerapp.core_local_storage.di
+
+import com.codandotv.streamplayerapp.core_local_storage.data.database.AppDatabase
+import com.codandotv.streamplayerapp.core_local_storage.data.database.databaseInstance
+import org.koin.dsl.module
+
+object LocalStorageModule {
+ val module = module {
+ single { databaseInstance() }
+ single { get().favoriteDao() }
+ }
+}
\ No newline at end of file
diff --git a/core-local-storage/src/main/java/com/codandotv/streamplayerapp/core_local_storage/domain/model/MovieEntity.kt b/core-local-storage/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_local_storage/domain/model/MovieEntity.kt
similarity index 100%
rename from core-local-storage/src/main/java/com/codandotv/streamplayerapp/core_local_storage/domain/model/MovieEntity.kt
rename to core-local-storage/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_local_storage/domain/model/MovieEntity.kt
diff --git a/core-local-storage/src/iosMain/kotlin/com/codandotv/streamplayerapp/core_local_storage/data/database/AppDatabasePlatform.ios.kt b/core-local-storage/src/iosMain/kotlin/com/codandotv/streamplayerapp/core_local_storage/data/database/AppDatabasePlatform.ios.kt
new file mode 100644
index 00000000..469b746b
--- /dev/null
+++ b/core-local-storage/src/iosMain/kotlin/com/codandotv/streamplayerapp/core_local_storage/data/database/AppDatabasePlatform.ios.kt
@@ -0,0 +1,35 @@
+package com.codandotv.streamplayerapp.core_local_storage.data.database
+
+import androidx.room.Room
+import androidx.room.util.findDatabaseConstructorAndInitDatabaseImpl
+import androidx.sqlite.driver.bundled.BundledSQLiteDriver
+import kotlinx.cinterop.ExperimentalForeignApi
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.IO
+import platform.Foundation.NSDocumentDirectory
+import platform.Foundation.NSFileManager
+import platform.Foundation.NSURL
+import platform.Foundation.NSUserDomainMask
+
+@OptIn(ExperimentalForeignApi::class)
+private fun documentDirectory(): String {
+ val documentDirectory: NSURL? = NSFileManager.defaultManager.URLForDirectory(
+ directory = NSDocumentDirectory,
+ inDomain = NSUserDomainMask,
+ appropriateForURL = null,
+ create = false,
+ error = null
+ )
+ return requireNotNull(documentDirectory).path!!
+}
+
+actual fun databaseInstance(): AppDatabase {
+ val dbFile = "${documentDirectory()}/$dbFileName"
+ return Room.databaseBuilder(
+ name = dbFile,
+ factory = { findDatabaseConstructorAndInitDatabaseImpl(AppDatabase::class) }
+ ).setDriver(BundledSQLiteDriver())
+ .setQueryCoroutineContext(Dispatchers.IO)
+ .build()
+}
+
diff --git a/core-local-storage/src/main/java/com/codandotv/streamplayerapp/core_local_storage/data/database/StreamPlayerAppDatabase.kt b/core-local-storage/src/main/java/com/codandotv/streamplayerapp/core_local_storage/data/database/StreamPlayerAppDatabase.kt
deleted file mode 100644
index d5d60723..00000000
--- a/core-local-storage/src/main/java/com/codandotv/streamplayerapp/core_local_storage/data/database/StreamPlayerAppDatabase.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.codandotv.streamplayerapp.core_local_storage.data.database
-
-import android.content.Context
-import androidx.room.Database
-import androidx.room.Room
-import androidx.room.RoomDatabase
-import com.codandotv.streamplayerapp.core_local_storage.data.dao.FavoriteDao
-import com.codandotv.streamplayerapp.core_local_storage.domain.model.MovieEntity
-
-@Database(entities = [MovieEntity::class], version = 1)
-abstract class StreamPlayerAppDatabase : RoomDatabase() {
-
- abstract fun favoriteDao(): FavoriteDao
-
- companion object {
-
- private var instance: StreamPlayerAppDatabase? = null
-
- fun getInstance(context: Context): StreamPlayerAppDatabase {
- if (instance == null) {
- synchronized(this) {
- instance = Room.databaseBuilder(
- context.applicationContext,
- StreamPlayerAppDatabase::class.java,
- DATABASE_NAME
- ).build()
- }
- }
- return instance!!
- }
-
- const val DATABASE_NAME = "app-database.db"
- }
-}
\ No newline at end of file
diff --git a/core-local-storage/src/main/java/com/codandotv/streamplayerapp/core_local_storage/di/LocalStorageModule.kt b/core-local-storage/src/main/java/com/codandotv/streamplayerapp/core_local_storage/di/LocalStorageModule.kt
deleted file mode 100644
index a42c8854..00000000
--- a/core-local-storage/src/main/java/com/codandotv/streamplayerapp/core_local_storage/di/LocalStorageModule.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.codandotv.streamplayerapp.core_local_storage.di
-
-import androidx.room.Room
-import com.codandotv.streamplayerapp.core_local_storage.data.database.StreamPlayerAppDatabase
-import com.codandotv.streamplayerapp.core_local_storage.data.database.StreamPlayerAppDatabase.Companion.DATABASE_NAME
-import org.koin.android.ext.koin.androidContext
-import org.koin.dsl.module
-
-object LocalStorageModule {
- val module = module {
- single { Room.databaseBuilder(androidContext(), StreamPlayerAppDatabase::class.java, DATABASE_NAME).build() }
- single { StreamPlayerAppDatabase.getInstance(get()) }
- single { get().favoriteDao() }
- }
-}
\ No newline at end of file
diff --git a/core-navigation/build.gradle.kts b/core-navigation/build.gradle.kts
index f7a359d3..21fc6a77 100644
--- a/core-navigation/build.gradle.kts
+++ b/core-navigation/build.gradle.kts
@@ -1,9 +1,17 @@
@file:Suppress("UnstableApiUsage")
plugins {
- id("com.streamplayer.android-library")
- id("com.streamplayer.compose")
+ id("com.streamplayer.kmp-library")
+ alias(libs.plugins.jetbrains.compose)
+ alias(libs.plugins.compose.compiler)
}
-dependencies {
- implementation(libs.bundles.kotlin)
+kotlin {
+ sourceSets {
+ commonMain.dependencies {
+ implementation(libs.navigation.compose)
+
+ implementation(compose.material3)
+ implementation(compose.components.resources)
+ }
+ }
}
\ No newline at end of file
diff --git a/core-navigation/src/main/res/drawable/ic_downloads_selected.xml b/core-navigation/src/commonMain/composeResources/drawable/ic_downloads_selected.xml
similarity index 91%
rename from core-navigation/src/main/res/drawable/ic_downloads_selected.xml
rename to core-navigation/src/commonMain/composeResources/drawable/ic_downloads_selected.xml
index e64c7219..93b67523 100644
--- a/core-navigation/src/main/res/drawable/ic_downloads_selected.xml
+++ b/core-navigation/src/commonMain/composeResources/drawable/ic_downloads_selected.xml
@@ -3,8 +3,8 @@
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
- android:tint="@android:color/white">
+ android:tint="#FFFFFF">
diff --git a/core-navigation/src/main/res/drawable/ic_downloads_unselected.xml b/core-navigation/src/commonMain/composeResources/drawable/ic_downloads_unselected.xml
similarity index 91%
rename from core-navigation/src/main/res/drawable/ic_downloads_unselected.xml
rename to core-navigation/src/commonMain/composeResources/drawable/ic_downloads_unselected.xml
index c23d8c3b..c85cae47 100644
--- a/core-navigation/src/main/res/drawable/ic_downloads_unselected.xml
+++ b/core-navigation/src/commonMain/composeResources/drawable/ic_downloads_unselected.xml
@@ -3,8 +3,8 @@
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
- android:tint="@android:color/white">
+ android:tint="#FFFFFF">
diff --git a/core-navigation/src/main/res/drawable/ic_games_selected.xml b/core-navigation/src/commonMain/composeResources/drawable/ic_games_selected.xml
similarity index 94%
rename from core-navigation/src/main/res/drawable/ic_games_selected.xml
rename to core-navigation/src/commonMain/composeResources/drawable/ic_games_selected.xml
index 7108c3be..1b5f631c 100644
--- a/core-navigation/src/main/res/drawable/ic_games_selected.xml
+++ b/core-navigation/src/commonMain/composeResources/drawable/ic_games_selected.xml
@@ -3,8 +3,8 @@
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
- android:tint="@android:color/white">
+ android:tint="#FFFFFF">
diff --git a/core-navigation/src/main/res/drawable/ic_games_unselected.xml b/core-navigation/src/commonMain/composeResources/drawable/ic_games_unselected.xml
similarity index 96%
rename from core-navigation/src/main/res/drawable/ic_games_unselected.xml
rename to core-navigation/src/commonMain/composeResources/drawable/ic_games_unselected.xml
index 1b02d38d..ebad3d46 100644
--- a/core-navigation/src/main/res/drawable/ic_games_unselected.xml
+++ b/core-navigation/src/commonMain/composeResources/drawable/ic_games_unselected.xml
@@ -3,8 +3,8 @@
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
- android:tint="@android:color/white">
+ android:tint="#FFFFFF">
diff --git a/core-navigation/src/main/res/drawable/ic_home_selected.xml b/core-navigation/src/commonMain/composeResources/drawable/ic_home_selected.xml
similarity index 85%
rename from core-navigation/src/main/res/drawable/ic_home_selected.xml
rename to core-navigation/src/commonMain/composeResources/drawable/ic_home_selected.xml
index 1ce23235..16cfe658 100644
--- a/core-navigation/src/main/res/drawable/ic_home_selected.xml
+++ b/core-navigation/src/commonMain/composeResources/drawable/ic_home_selected.xml
@@ -3,8 +3,8 @@
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
- android:tint="@android:color/white">
+ android:tint="#FFFFFF">
diff --git a/core-navigation/src/main/res/drawable/ic_home_unselected.xml b/core-navigation/src/commonMain/composeResources/drawable/ic_home_unselected.xml
similarity index 84%
rename from core-navigation/src/main/res/drawable/ic_home_unselected.xml
rename to core-navigation/src/commonMain/composeResources/drawable/ic_home_unselected.xml
index 5dc49b78..9517ebda 100644
--- a/core-navigation/src/main/res/drawable/ic_home_unselected.xml
+++ b/core-navigation/src/commonMain/composeResources/drawable/ic_home_unselected.xml
@@ -3,8 +3,8 @@
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
- android:tint="@android:color/white">
+ android:tint="#FFFFFF">
diff --git a/core-navigation/src/main/res/drawable/ic_news_selected.xml b/core-navigation/src/commonMain/composeResources/drawable/ic_news_selected.xml
similarity index 94%
rename from core-navigation/src/main/res/drawable/ic_news_selected.xml
rename to core-navigation/src/commonMain/composeResources/drawable/ic_news_selected.xml
index 50b53635..48906958 100644
--- a/core-navigation/src/main/res/drawable/ic_news_selected.xml
+++ b/core-navigation/src/commonMain/composeResources/drawable/ic_news_selected.xml
@@ -5,6 +5,6 @@
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
diff --git a/core-navigation/src/main/res/drawable/ic_news_unselected.xml b/core-navigation/src/commonMain/composeResources/drawable/ic_news_unselected.xml
similarity index 90%
rename from core-navigation/src/main/res/drawable/ic_news_unselected.xml
rename to core-navigation/src/commonMain/composeResources/drawable/ic_news_unselected.xml
index b4d4c7a5..45cfe6ac 100644
--- a/core-navigation/src/main/res/drawable/ic_news_unselected.xml
+++ b/core-navigation/src/commonMain/composeResources/drawable/ic_news_unselected.xml
@@ -3,8 +3,8 @@
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
- android:tint="@android:color/white">
+ android:tint="#FFFFFF">
diff --git a/core-navigation/src/main/res/values/strings.xml b/core-navigation/src/commonMain/composeResources/values/strings.xml
similarity index 100%
rename from core-navigation/src/main/res/values/strings.xml
rename to core-navigation/src/commonMain/composeResources/values/strings.xml
diff --git a/core-navigation/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_navigation/bottomnavigation/BottomNavItem.kt b/core-navigation/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_navigation/bottomnavigation/BottomNavItem.kt
new file mode 100644
index 00000000..96c2e576
--- /dev/null
+++ b/core-navigation/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_navigation/bottomnavigation/BottomNavItem.kt
@@ -0,0 +1,56 @@
+package com.codandotv.streamplayerapp.core_navigation.bottomnavigation
+
+import com.codandotv.streamplayerapp.core_navigation.routes.BottomNavRoutes
+import org.jetbrains.compose.resources.DrawableResource
+import org.jetbrains.compose.resources.StringResource
+import streamplayerapp_kmp.core_navigation.generated.resources.Res
+import streamplayerapp_kmp.core_navigation.generated.resources.bottom_nav_downloads
+import streamplayerapp_kmp.core_navigation.generated.resources.bottom_nav_games
+import streamplayerapp_kmp.core_navigation.generated.resources.bottom_nav_home
+import streamplayerapp_kmp.core_navigation.generated.resources.bottom_nav_news
+import streamplayerapp_kmp.core_navigation.generated.resources.ic_downloads_selected
+import streamplayerapp_kmp.core_navigation.generated.resources.ic_downloads_unselected
+import streamplayerapp_kmp.core_navigation.generated.resources.ic_games_selected
+import streamplayerapp_kmp.core_navigation.generated.resources.ic_games_unselected
+import streamplayerapp_kmp.core_navigation.generated.resources.ic_home_selected
+import streamplayerapp_kmp.core_navigation.generated.resources.ic_home_unselected
+import streamplayerapp_kmp.core_navigation.generated.resources.ic_news_selected
+import streamplayerapp_kmp.core_navigation.generated.resources.ic_news_unselected
+
+sealed class BottomNavItem(
+ val title: StringResource,
+ val iconUnselected: DrawableResource,
+ val iconSelected: DrawableResource,
+ val screenRoute: String
+) {
+ object Home :
+ BottomNavItem(
+ Res.string.bottom_nav_home,
+ Res.drawable.ic_home_unselected,
+ Res.drawable.ic_home_selected,
+ BottomNavRoutes.HOME
+ )
+
+ object Games :
+ BottomNavItem(
+ Res.string.bottom_nav_games,
+ Res.drawable.ic_games_unselected,
+ Res.drawable.ic_games_selected,
+ BottomNavRoutes.GAMES
+ )
+
+ object News :
+ BottomNavItem(
+ Res.string.bottom_nav_news,
+ Res.drawable.ic_news_unselected,
+ Res.drawable.ic_news_selected,
+ BottomNavRoutes.NEWS
+ )
+
+ object Downloads : BottomNavItem(
+ Res.string.bottom_nav_downloads,
+ Res.drawable.ic_downloads_unselected,
+ Res.drawable.ic_downloads_selected,
+ BottomNavRoutes.DOWNLOADS
+ )
+}
\ No newline at end of file
diff --git a/core-navigation/src/main/java/com/codandotv/streamplayerapp/core_navigation/bottomnavigation/StreamPlayerBottomNavigation.kt b/core-navigation/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_navigation/bottomnavigation/StreamPlayerBottomNavigation.kt
similarity index 88%
rename from core-navigation/src/main/java/com/codandotv/streamplayerapp/core_navigation/bottomnavigation/StreamPlayerBottomNavigation.kt
rename to core-navigation/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_navigation/bottomnavigation/StreamPlayerBottomNavigation.kt
index aa9375b0..f4096a3a 100644
--- a/core-navigation/src/main/java/com/codandotv/streamplayerapp/core_navigation/bottomnavigation/StreamPlayerBottomNavigation.kt
+++ b/core-navigation/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_navigation/bottomnavigation/StreamPlayerBottomNavigation.kt
@@ -11,11 +11,11 @@ import androidx.compose.material3.Text
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.codandotv.streamplayerapp.core_navigation.helper.currentRoute
+import org.jetbrains.compose.resources.painterResource
+import org.jetbrains.compose.resources.stringResource
private val bottomMenuItems = listOf(
BottomNavItem.Home,
@@ -46,7 +46,7 @@ fun StreamPlayerBottomNavigation(navController: NavController) {
icon = { NavItemIcon(currentRoute, item) },
label = {
Text(
- text = stringResource(id = item.title),
+ text = stringResource(item.title),
style = MaterialTheme.typography.bodySmall,
)
},
@@ -62,8 +62,8 @@ private fun NavItemIcon(
item: BottomNavItem
) {
Icon(
- painterResource(id = if (currentRoute == item.screenRoute) item.iconSelected else item.iconUnselected),
- contentDescription = stringResource(id = item.title),
+ painterResource(if (currentRoute == item.screenRoute) item.iconSelected else item.iconUnselected),
+ contentDescription = stringResource(item.title),
)
}
diff --git a/core-navigation/src/main/java/com/codandotv/streamplayerapp/core_navigation/extensions/NavControllerExtension.kt b/core-navigation/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_navigation/extensions/NavControllerExtension.kt
similarity index 100%
rename from core-navigation/src/main/java/com/codandotv/streamplayerapp/core_navigation/extensions/NavControllerExtension.kt
rename to core-navigation/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_navigation/extensions/NavControllerExtension.kt
diff --git a/core-navigation/src/main/java/com/codandotv/streamplayerapp/core_navigation/helper/NavigationHelper.kt b/core-navigation/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_navigation/helper/NavigationHelper.kt
similarity index 100%
rename from core-navigation/src/main/java/com/codandotv/streamplayerapp/core_navigation/helper/NavigationHelper.kt
rename to core-navigation/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_navigation/helper/NavigationHelper.kt
diff --git a/core-navigation/src/main/java/com/codandotv/streamplayerapp/core_navigation/routes/BottomNavRoutes.kt b/core-navigation/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_navigation/routes/BottomNavRoutes.kt
similarity index 100%
rename from core-navigation/src/main/java/com/codandotv/streamplayerapp/core_navigation/routes/BottomNavRoutes.kt
rename to core-navigation/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_navigation/routes/BottomNavRoutes.kt
diff --git a/core-navigation/src/main/java/com/codandotv/streamplayerapp/core_navigation/routes/Routes.kt b/core-navigation/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_navigation/routes/Routes.kt
similarity index 87%
rename from core-navigation/src/main/java/com/codandotv/streamplayerapp/core_navigation/routes/Routes.kt
rename to core-navigation/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_navigation/routes/Routes.kt
index 572636d9..552cfc46 100644
--- a/core-navigation/src/main/java/com/codandotv/streamplayerapp/core_navigation/routes/Routes.kt
+++ b/core-navigation/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_navigation/routes/Routes.kt
@@ -4,7 +4,7 @@ import com.codandotv.streamplayerapp.core_navigation.routes.Routes.PARAM.ID
object Routes {
const val DETAIL = "DetailList/"
- const val DETAIL_COMPLETE = "${DETAIL}{${ID}}"
+ const val DETAIL_COMPLETE = "$DETAIL{${ID}}"
const val Splash = "splash"
const val SEARCH = "Search"
const val PROFILE_PICKER = "profilePicker"
diff --git a/core-navigation/src/main/java/com/codandotv/streamplayerapp/core_navigation/bottomnavigation/BottomNavItem.kt b/core-navigation/src/main/java/com/codandotv/streamplayerapp/core_navigation/bottomnavigation/BottomNavItem.kt
deleted file mode 100644
index b7cfb7b4..00000000
--- a/core-navigation/src/main/java/com/codandotv/streamplayerapp/core_navigation/bottomnavigation/BottomNavItem.kt
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.codandotv.streamplayerapp.core_navigation.bottomnavigation
-
-import androidx.annotation.DrawableRes
-import androidx.annotation.StringRes
-import com.codandotv.streamplayerapp.core.navigation.R
-import com.codandotv.streamplayerapp.core_navigation.routes.BottomNavRoutes
-
-sealed class BottomNavItem(
- @StringRes var title: Int,
- @DrawableRes var iconUnselected: Int,
- @DrawableRes var iconSelected: Int,
- var screenRoute: String
-) {
- object Home :
- BottomNavItem(
- R.string.bottom_nav_home,
- R.drawable.ic_home_unselected,
- R.drawable.ic_home_selected,
- BottomNavRoutes.HOME
- )
-
- object Games :
- BottomNavItem(
- R.string.bottom_nav_games,
- R.drawable.ic_games_unselected,
- R.drawable.ic_games_selected,
- BottomNavRoutes.GAMES
- )
-
- object News :
- BottomNavItem(
- R.string.bottom_nav_news,
- R.drawable.ic_news_unselected,
- R.drawable.ic_news_selected,
- BottomNavRoutes.NEWS
- )
-
- object Downloads : BottomNavItem(
- R.string.bottom_nav_downloads,
- R.drawable.ic_downloads_unselected,
- R.drawable.ic_downloads_selected,
- BottomNavRoutes.DOWNLOADS
- )
-}
\ No newline at end of file
diff --git a/core-networking/build.gradle.kts b/core-networking/build.gradle.kts
index f5602562..367251c8 100644
--- a/core-networking/build.gradle.kts
+++ b/core-networking/build.gradle.kts
@@ -1,27 +1,54 @@
+import com.codingfeline.buildkonfig.compiler.FieldSpec
+
plugins {
- id("com.streamplayer.android-library")
+ id("com.streamplayer.kmp-library")
+ alias(libs.plugins.jetbrains.compose)
+ alias(libs.plugins.compose.compiler)
+ alias(libs.plugins.buildkonfig.plugin)
}
-android {
- buildFeatures {
- buildConfig = true
+
+buildkonfig {
+ packageName = "core.networking"
+
+ defaultConfigs {
+ 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)
}
- 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)
+}
+
+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)
}
- 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)
+
+ androidMain.dependencies {
+ implementation(libs.okhttp)
+
+ implementation(libs.interceptor)
+
+ implementation(libs.ktor.client.okhttp)
+ }
+
+ iosMain.dependencies {
+ implementation(libs.ktor.client.darwin)
}
}
-}
-dependencies {
- implementation(libs.bundles.kotlin)
- implementation(libs.bundles.networking)
- implementation(libs.bundles.koin)
- testImplementation(libs.bundles.test)
-}
+}
\ No newline at end of file
diff --git a/core-networking/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProviderPlatform.android.kt b/core-networking/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProviderPlatform.android.kt
new file mode 100644
index 00000000..5373464e
--- /dev/null
+++ b/core-networking/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProviderPlatform.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 httpClientEnginePlatform() : HttpClientEngine = OkHttpEngine(OkHttpConfig())
\ No newline at end of file
diff --git a/core-networking/src/main/res/values/strings.xml b/core-networking/src/commonMain/composeResources/values/strings.xml
similarity index 100%
rename from core-networking/src/main/res/values/strings.xml
rename to core-networking/src/commonMain/composeResources/values/strings.xml
diff --git a/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProviderPlatform.kt b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProviderPlatform.kt
new file mode 100644
index 00000000..40eb9de0
--- /dev/null
+++ b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProviderPlatform.kt
@@ -0,0 +1,5 @@
+package com.codandotv.streamplayerapp.core_networking
+
+import io.ktor.client.engine.HttpClientEngine
+
+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
new file mode 100644
index 00000000..a55c169b
--- /dev/null
+++ b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/di/NetworkModule.kt
@@ -0,0 +1,92 @@
+package com.codandotv.streamplayerapp.core_networking.di
+
+import com.codandotv.streamplayerapp.core_networking.di.Network.TIMEOUT
+import com.codandotv.streamplayerapp.core_networking.httpClientEnginePlatform
+import core.networking.BuildKonfig
+import io.ktor.client.HttpClient
+import io.ktor.client.plugins.HttpTimeout
+import io.ktor.client.plugins.auth.Auth
+import io.ktor.client.plugins.auth.providers.BearerTokens
+import io.ktor.client.plugins.auth.providers.bearer
+import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
+import io.ktor.client.plugins.defaultRequest
+import io.ktor.client.plugins.logging.LogLevel
+import io.ktor.client.plugins.logging.Logger
+import io.ktor.client.plugins.logging.Logging
+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.json.Json
+import org.koin.dsl.module
+
+object NetworkModule {
+ val module = module {
+ single(QualifierHost) { BuildKonfig.HOST }
+ single(QualifierProfile) { BuildKonfig.PROFILE }
+
+ single {
+ provideKtorHttpClient(
+ baseUrl = get(QualifierHost),
+ )
+ }
+
+ single(QualifierProfileHttpClient) {
+ provideKtorHttpClient(
+ baseUrl = get(QualifierProfile),
+ )
+ }
+ }
+
+ private fun provideKtorHttpClient(
+ baseUrl: String,
+ ): HttpClient {
+ return HttpClient(engine = httpClientEnginePlatform()) {
+ expectSuccess = false
+
+ install(ContentNegotiation) {
+ json(Json {
+ explicitNulls = false
+ ignoreUnknownKeys = true
+ })
+ }
+
+ install(HttpTimeout) {
+ socketTimeoutMillis = TIMEOUT
+ requestTimeoutMillis = TIMEOUT
+ connectTimeoutMillis = TIMEOUT
+ }
+
+ defaultRequest {
+ url(baseUrl)
+ contentType(ContentType.Application.Json)
+ accept(ContentType.Application.Json)
+ }
+
+ install(Auth) {
+ bearer {
+ loadTokens {
+ BearerTokens(
+ accessToken = BuildKonfig.API_BEARER_AUTH,
+ refreshToken = ""
+ )
+ }
+ }
+ }
+
+ install(Logging) {
+ level = LogLevel.ALL
+ logger = object : Logger {
+ override fun log(message: String) {
+ //TODO: Migrar Logs para Utilizar Kermit
+ println("HttpClient${message}")
+ }
+ }
+ }
+ }
+ }
+}
+
+internal object Network {
+ const val TIMEOUT = 10000L
+}
\ No newline at end of file
diff --git a/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/di/QualifierNetworking.kt b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/di/QualifierNetworking.kt
similarity index 93%
rename from core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/di/QualifierNetworking.kt
rename to core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/di/QualifierNetworking.kt
index c3564c8f..b21a5e27 100644
--- a/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/di/QualifierNetworking.kt
+++ b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/di/QualifierNetworking.kt
@@ -13,12 +13,11 @@ object QualifierProfile : Qualifier {
get() = "QualifierProfile"
}
-object QualifierProfileRetrofit : Qualifier {
+object QualifierProfileHttpClient : Qualifier {
override val value: QualifierValue
get() = "QualifierProfileRetrofit"
}
-
object QualifierLoggerInterceptor : Qualifier {
override val value: QualifierValue
get() = "QualifierLoggerInterceptor"
diff --git a/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/handleError/Failure.kt b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/handleError/Failure.kt
similarity index 71%
rename from core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/handleError/Failure.kt
rename to core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/handleError/Failure.kt
index eeb1421a..f09b8b03 100644
--- a/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/handleError/Failure.kt
+++ b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/handleError/Failure.kt
@@ -1,6 +1,7 @@
package com.codandotv.streamplayerapp.core_networking.handleError
-import com.codandotv.streamplayerapp.core.networking.R
+import com.codandotv.streamplayerapp.core_networking.resources.StringNetworking
+import kotlinx.serialization.Serializable
import org.koin.core.component.KoinComponent
/**
@@ -11,19 +12,21 @@ import org.koin.core.component.KoinComponent
"TooGenericExceptionCaught",
"MagicNumber"
)
+
+@Serializable
sealed class Failure(
val code: Int? = -1,
val errorMessage: String? = null,
- val errorMessageRes: Int = R.string.core_networking_msg_default_error
+ val errorMessageResKey: String = StringNetworking.msgDefaultErrorKey()
) : Exception(), KoinComponent {
data class NoDataContent(val codeStatus: Int? = null) :
- Failure(codeStatus, errorMessageRes = R.string.core_networking_no_data_content)
+ Failure(codeStatus, errorMessageResKey = StringNetworking.msgNoDataContentKey())
data class ServerError(val codeStatus: Int? = null) :
- Failure(codeStatus, errorMessageRes = R.string.core_networking_no_server_error)
+ Failure(codeStatus, errorMessageResKey = StringNetworking.msgServerErrorKey())
data class GenericError(
- val codeStatus: Int? = -12, private val msg: String? = null
+ val codeStatus: Int? = -12, private val msg: String? = StringNetworking.msgNetworkErrorKey()
) : Failure(
codeStatus
)
@@ -31,7 +34,7 @@ sealed class Failure(
data class NetworkError(
val codeStatus: Int? = -13, private val throwable: Throwable
) : Failure(
- codeStatus, errorMessageRes = R.string.core_networking_networking_error
+ codeStatus, errorMessageResKey = StringNetworking.msgNetworkErrorKey()
)
data class UnknownError(
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
new file mode 100644
index 00000000..5ccadb2c
--- /dev/null
+++ b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/handleError/HttpClientConfigExtensions.kt
@@ -0,0 +1,35 @@
+package com.codandotv.streamplayerapp.core_networking.handleError
+
+import io.ktor.client.HttpClient
+import io.ktor.client.call.body
+import io.ktor.client.plugins.ClientRequestException
+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
+
+suspend inline fun HttpClient.safeRequest(
+ block: HttpRequestBuilder.() -> Unit,
+): NetworkResponse =
+ try {
+ val response = request { block() }
+ NetworkResponse.Success(response.body())
+ } catch (exception: ClientRequestException) {
+ NetworkResponse.Error(
+ body = exception.response.bodyAsText(),
+ exception = Failure.ServerError(exception.response.status.value)
+ )
+ } catch (e: SerializationException) {
+ NetworkResponse.Error(
+ exception = Failure.UnparsableResponseException(throwable = e)
+ )
+ } catch (e: IOException) {
+ NetworkResponse.Error(
+ exception = Failure.NetworkError(throwable = e)
+ )
+ } catch (e: Exception) {
+ NetworkResponse.Error(
+ exception = Failure.GenericError(msg = e.message ?: "Unknown error")
+ )
+ }
diff --git a/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/handleError/NetworkResponse.kt b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/handleError/NetworkResponse.kt
similarity index 86%
rename from core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/handleError/NetworkResponse.kt
rename to core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/handleError/NetworkResponse.kt
index ca705691..51378aab 100644
--- a/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/handleError/NetworkResponse.kt
+++ b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/handleError/NetworkResponse.kt
@@ -2,14 +2,19 @@ package com.codandotv.streamplayerapp.core_networking.handleError
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.Transient
+@Serializable
sealed class NetworkResponse {
+ @Serializable
data class Success(
val value: T
) : NetworkResponse()
+ @Serializable
data class Error(
- val body: Any? = null,
+ val body: String? = null,
@Transient
val exception: Failure? = null
) : NetworkResponse()
diff --git a/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/handleError/ResultExtensions.kt b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/handleError/ResultExtensions.kt
similarity index 100%
rename from core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/handleError/ResultExtensions.kt
rename to core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/handleError/ResultExtensions.kt
diff --git a/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/resources/StringNetworking.kt b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/resources/StringNetworking.kt
new file mode 100644
index 00000000..b7edb0a2
--- /dev/null
+++ b/core-networking/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_networking/resources/StringNetworking.kt
@@ -0,0 +1,25 @@
+package com.codandotv.streamplayerapp.core_networking.resources
+
+import org.jetbrains.compose.resources.StringResource
+import streamplayerapp_kmp.core_networking.generated.resources.Res
+import streamplayerapp_kmp.core_networking.generated.resources.core_networking_msg_default_error
+import streamplayerapp_kmp.core_networking.generated.resources.core_networking_networking_error
+import streamplayerapp_kmp.core_networking.generated.resources.core_networking_no_data_content
+import streamplayerapp_kmp.core_networking.generated.resources.core_networking_no_server_error
+
+//Note: done this to search for strings in the innermost layers because you can't use them because they are not composable
+object StringNetworking {
+ internal fun msgDefaultErrorKey(): String = Res.string.core_networking_msg_default_error.key
+ internal fun msgNoDataContentKey(): String = Res.string.core_networking_no_data_content.key
+ internal fun msgServerErrorKey(): String = Res.string.core_networking_no_server_error.key
+ internal fun msgNetworkErrorKey(): String = Res.string.core_networking_networking_error.key
+
+ private val errorMessageMap = mapOf(
+ msgDefaultErrorKey() to Res.string.core_networking_msg_default_error,
+ msgNoDataContentKey() to Res.string.core_networking_no_data_content,
+ msgServerErrorKey() to Res.string.core_networking_no_server_error,
+ msgNetworkErrorKey() to Res.string.core_networking_networking_error
+ )
+
+ fun getStringResource(key: String): StringResource? = errorMessageMap[key]
+}
diff --git a/core-networking/src/iosMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProviderPlatform.ios.kt b/core-networking/src/iosMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProviderPlatform.ios.kt
new file mode 100644
index 00000000..9470ffa4
--- /dev/null
+++ b/core-networking/src/iosMain/kotlin/com/codandotv/streamplayerapp/core_networking/HttpClientEngineProviderPlatform.ios.kt
@@ -0,0 +1,8 @@
+package com.codandotv.streamplayerapp.core_networking
+
+import io.ktor.client.engine.HttpClientEngine
+import io.ktor.client.engine.darwin.Darwin
+
+actual fun httpClientEnginePlatform(): HttpClientEngine {
+ return Darwin.create()
+}
\ No newline at end of file
diff --git a/core-networking/src/main/AndroidManifest.xml b/core-networking/src/main/AndroidManifest.xml
deleted file mode 100644
index a8800291..00000000
--- a/core-networking/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/coroutines/NetworkResponseAdapter.kt b/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/coroutines/NetworkResponseAdapter.kt
deleted file mode 100644
index eafeb5b9..00000000
--- a/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/coroutines/NetworkResponseAdapter.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.codandotv.streamplayerapp.core_networking.coroutines
-
-import com.squareup.moshi.Moshi
-import retrofit2.Call
-import retrofit2.CallAdapter
-import java.lang.reflect.Type
-
-class NetworkResponseAdapter(
- private val responseType: Type,
- private val moshi: Moshi
-): CallAdapter {
-
- override fun responseType(): Type = responseType
- override fun adapt(call: Call) = NetworkResponseCall(call,moshi)
-}
\ No newline at end of file
diff --git a/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/coroutines/NetworkResponseAdapterFactory.kt b/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/coroutines/NetworkResponseAdapterFactory.kt
deleted file mode 100644
index d2626078..00000000
--- a/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/coroutines/NetworkResponseAdapterFactory.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-package com.codandotv.streamplayerapp.core_networking.coroutines
-
-import com.codandotv.streamplayerapp.core_networking.handleError.NetworkResponse
-import com.squareup.moshi.Moshi
-import retrofit2.Call
-import retrofit2.CallAdapter
-import retrofit2.Retrofit
-import java.lang.reflect.ParameterizedType
-import java.lang.reflect.Type
-
-@Suppress("ReturnCount", "SwallowedException")
-class NetworkResponseAdapterFactory(private val moshi: Moshi) : CallAdapter.Factory() {
- override fun get(
- returnType: Type,
- annotations: Array,
- retrofit: Retrofit
- ): CallAdapter<*, *>? {
- return try {
- // suspend functions wrap the response type in `Call`
- if (Call::class.java != getRawType(returnType)) {
- return null
- }
-
- // check first that the return type is `ParameterizedType`
- check(returnType is ParameterizedType) {
- "return type must be parameterized as Call> or Call>"
- }
-
- // get the response type inside the `Call` type
- val responseType = getParameterUpperBound(0, returnType)
-
- // if the response type is not ApiResponse then we can't handle this type, so we return null
- if (getRawType(responseType) != NetworkResponse::class.java) {
- return null
- }
-
- // the response type is ApiResponse and should be parameterized
- check(responseType is ParameterizedType) {
- "Response must be parameterized as NetworkResponse " +
- "or NetworkResponse"
- }
-
- val successBodyType = getParameterUpperBound(0, responseType)
-
- return NetworkResponseAdapter(successBodyType, moshi)
- } catch (ex: ClassCastException) {
- null
- }
- }
-}
\ No newline at end of file
diff --git a/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/coroutines/NetworkResponseCall.kt b/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/coroutines/NetworkResponseCall.kt
deleted file mode 100644
index 710ad937..00000000
--- a/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/coroutines/NetworkResponseCall.kt
+++ /dev/null
@@ -1,158 +0,0 @@
-package com.codandotv.streamplayerapp.core_networking.coroutines
-
-import com.codandotv.streamplayerapp.core_networking.handleError.Failure
-import com.codandotv.streamplayerapp.core_networking.handleError.NetworkResponse
-import com.squareup.moshi.Moshi
-import okhttp3.Request
-import okhttp3.ResponseBody
-import okio.Timeout
-import retrofit2.Call
-import retrofit2.Callback
-import retrofit2.HttpException
-import retrofit2.Response
-import java.io.IOException
-
-@Suppress("SwallowedException", "TooGenericExceptionCaught")
-class NetworkResponseCall(
- proxy: Call,
- private val moshi: Moshi
-) :
- CallDelegate>(proxy) {
-
- override fun enqueueImpl(callback: Callback>) =
- proxy.enqueue(object : Callback {
- override fun onResponse(call: Call, response: Response) {
- val body = response.body()
- val code = response.code()
- val error = response.errorBody()
- if (response.isSuccessful) {
- responseSuccessful(body, callback, code)
- } else {
- responseError(callback,error, code)
- }
- }
-
- override fun onFailure(call: Call, throwable: Throwable) {
- val networkResponse = when (throwable) {
- is IOException -> Failure.NetworkError(throwable = throwable)
- is HttpException -> convertException(throwable)
- else -> Failure.GenericError(msg = throwable.message)
- }
- callback.onResponse(
- this@NetworkResponseCall,
- Response.success(NetworkResponse.Error(exception = networkResponse))
- )
- }
-
-
- private fun convertException(exception: HttpException): Failure {
- return try {
- val response = getErrorResponse(exception)
- Failure.UnexpectedApiException(throwable = response.exception)
- } catch (ex: Failure.ClientException) {
- ex
- }catch (ex : Failure.UnparsableResponseException){
- ex
- }
- }
-
- private fun getErrorResponse(ex: HttpException): NetworkResponse.Error {
- val error = ex.response()?.errorBody()?.string()
- if (error?.isEmpty() != false) {
- throw Failure.ClientException(throwable = ex)
- }
- return parseError(error, ex)
- }
-
- private fun parseError(error: String, ex: HttpException): NetworkResponse.Error {
- try {
- return moshi
- .adapter(NetworkResponse.Error::class.java)
- .fromJson(error)!!
- } catch (e: Exception) {
- throw Failure.UnparsableResponseException(throwable = ex)
- }
- }
- })
-
- private fun responseSuccessful(
- body: T?,
- callback: Callback>,
- code: Int
- ) {
- if (body != null) {
- callback.onResponse(
- this@NetworkResponseCall,
- Response.success(NetworkResponse.Success(body))
- )
- } else {
- callback.onResponse(
- this@NetworkResponseCall,
- Response.success(
- NetworkResponse.Error(
- exception = Failure.NoDataContent(
- code
- )
- )
- )
- )
- }
- }
-
- private fun responseError(callback: Callback>, error: ResponseBody?, code: Int) {
- val errorBody = when {
- error == null -> null
- error.contentLength() == 0L -> null
- else -> try {
- moshi
- .adapter(NetworkResponse.Error::class.java)
- .fromJson(error.string())
- } catch (ex: Exception) {
- null
- }
- }
- if (errorBody != null) {
- callback.onResponse(
- this@NetworkResponseCall,
- Response.success(
- NetworkResponse.Error(
- body = errorBody,
- exception = Failure.ServerError(code)
- )
- )
- )
- } else {
- callback.onResponse(
- this@NetworkResponseCall,
- Response.success(
- NetworkResponse.Error(
- exception = Failure.UnknownError(
- code
- )
- )
- )
- )
- }
- }
-
-
- override fun cloneImpl(): Call> =
- NetworkResponseCall(proxy.clone(), moshi)
-}
-
-abstract class CallDelegate(
- protected val proxy: Call
-) : Call {
- override fun execute(): Response = throw NotImplementedError()
- final override fun enqueue(callback: Callback) = enqueueImpl(callback)
- final override fun clone(): Call = cloneImpl()
-
- override fun cancel() = proxy.cancel()
- override fun request(): Request = proxy.request()
- override fun isExecuted() = proxy.isExecuted
- override fun isCanceled() = proxy.isCanceled
-
- abstract fun enqueueImpl(callback: Callback)
- abstract fun cloneImpl(): Call
- override fun timeout(): Timeout = proxy.timeout()
-}
\ No newline at end of file
diff --git a/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/di/NetworkModule.kt b/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/di/NetworkModule.kt
deleted file mode 100644
index 7b0dc322..00000000
--- a/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/di/NetworkModule.kt
+++ /dev/null
@@ -1,103 +0,0 @@
-package com.codandotv.streamplayerapp.core_networking.di
-
-import com.codandotv.streamplayerapp.core.networking.BuildConfig
-import com.codandotv.streamplayerapp.core_networking.coroutines.NetworkResponseAdapterFactory
-import com.squareup.moshi.Moshi
-import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
-import okhttp3.Interceptor
-import okhttp3.OkHttpClient
-import okhttp3.logging.HttpLoggingInterceptor
-import org.koin.dsl.module
-import retrofit2.Retrofit
-import retrofit2.converter.moshi.MoshiConverterFactory
-import java.util.concurrent.TimeUnit
-
-@Suppress("MagicNumber")
-object NetworkModule {
- val module = module {
- single(QualifierHost) {
- BuildConfig.HOST
- }
-
- single(QualifierProfile) {
- BuildConfig.PROFILE
- }
-
- single {
- Moshi.Builder()
- .add(KotlinJsonAdapterFactory())
- .build()
- }
-
- single(QualifierAuthInterceptor) {
- Interceptor { chain ->
- val newRequest =
- chain.request()
- .newBuilder()
- .addHeader(
- "Authorization",
- BuildConfig.API_BEARER_AUTH
- )
- .addHeader("Content-Type", "application/json;charset=utf-8")
- .build()
- chain.proceed(newRequest)
- }
- }
-
- single(QualifierLoggerInterceptor) {
- HttpLoggingInterceptor().setLevel(
- if (BuildConfig.DEBUG) {
- HttpLoggingInterceptor.Level.BODY
- } else {
- HttpLoggingInterceptor.Level.NONE
- }
- )
- }
- single {
- provideRetrofit(
- okHttpClient = get(),
- moshi = get(),
- baseUrl = get(QualifierHost)
- )
- }
-
- single(QualifierProfileRetrofit) {
- provideRetrofit(
- okHttpClient = get(),
- moshi = get(),
- baseUrl = get(QualifierProfile)
- )
- }
-
- single {
- provideOkhttp(
- get(QualifierAuthInterceptor),
- get(QualifierLoggerInterceptor),
- )
- }
- }
-
- private fun provideOkhttp(
- vararg interceptor: Interceptor
- ): OkHttpClient {
- val okHttpClientBuilder = OkHttpClient.Builder()
- interceptor.forEach {
- okHttpClientBuilder.addInterceptor(it)
- }
- return okHttpClientBuilder
- .connectTimeout(15, TimeUnit.SECONDS)
- .build()
- }
-
- private fun provideRetrofit(
- okHttpClient: OkHttpClient,
- moshi: Moshi,
- baseUrl: String
- ): Retrofit =
- Retrofit.Builder()
- .baseUrl(baseUrl)
- .client(okHttpClient)
- .addConverterFactory(MoshiConverterFactory.create(moshi))
- .addCallAdapterFactory(NetworkResponseAdapterFactory(moshi))
- .build()
-}
\ No newline at end of file
diff --git a/core-shared-ui/build.gradle.kts b/core-shared-ui/build.gradle.kts
index 5f46ed8a..9af7989e 100644
--- a/core-shared-ui/build.gradle.kts
+++ b/core-shared-ui/build.gradle.kts
@@ -1,15 +1,36 @@
@file:Suppress("UnstableApiUsage")
plugins {
- id("com.streamplayer.android-library")
- id("com.streamplayer.compose")
+ id("com.streamplayer.kmp-library")
+ alias(libs.plugins.jetbrains.compose)
+ alias(libs.plugins.compose.compiler)
}
-dependencies {
- implementation(projects.coreShared)
- implementation(libs.bundles.koin)
- implementation(libs.bundles.kotlin)
- implementation(libs.bundles.androidSupport)
- implementation(libs.android.youtube.player)
- testImplementation(libs.bundles.test)
- implementation(libs.coil)
-}
\ No newline at end of file
+kotlin {
+ sourceSets {
+ androidMain.dependencies {
+ implementation(compose.preview)
+ implementation(libs.android.youtube.player)
+ implementation(libs.ktor.client.okhttp)
+ }
+ commonMain.dependencies {
+ implementation(projects.coreShared)
+ implementation(compose.material3)
+ implementation(compose.ui)
+ implementation(compose.components.resources)
+ implementation(libs.navigation.compose)
+
+ implementation(libs.coil)
+ implementation(libs.coil.network.ktor3)
+
+ implementation(libs.paging.compose)
+ }
+
+ iosMain.dependencies {
+ implementation(libs.ktor.client.darwin)
+ }
+ }
+}
+
+compose.resources {
+ publicResClass = true
+}
diff --git a/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/extension/ErrorExtPlatform.android.kt b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/extension/ErrorExtPlatform.android.kt
new file mode 100644
index 00000000..eac583b7
--- /dev/null
+++ b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/extension/ErrorExtPlatform.android.kt
@@ -0,0 +1,10 @@
+package com.codandotv.streamplayerapp.core_shared_ui.extension
+
+import android.widget.Toast
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.LocalContext
+
+@Composable
+actual fun ShowErrorMessage(errorMessage: String) {
+ Toast.makeText(LocalContext.current,errorMessage,Toast.LENGTH_SHORT).show()
+}
\ No newline at end of file
diff --git a/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/extension/PackageExtension.kt b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/extension/PackageExtension.kt
new file mode 100644
index 00000000..b2131aad
--- /dev/null
+++ b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/extension/PackageExtension.kt
@@ -0,0 +1,12 @@
+package com.codandotv.streamplayerapp.core_shared_ui.extension
+
+import android.content.pm.PackageInfo
+import android.content.pm.PackageManager
+import android.os.Build
+
+fun PackageManager.getPackageInfoCompat(packageName: String, flags: Int = 0): PackageInfo =
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(flags.toLong()))
+ } else {
+ @Suppress("DEPRECATION") getPackageInfo(packageName, flags)
+ }
diff --git a/core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/theme/ThemePreviews.kt b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/theme/ThemePreviews.kt
similarity index 100%
rename from core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/theme/ThemePreviews.kt
rename to core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/theme/ThemePreviews.kt
diff --git a/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/utils/SharingPlatform.android.kt b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/utils/SharingPlatform.android.kt
new file mode 100644
index 00000000..1b9ab4c2
--- /dev/null
+++ b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/utils/SharingPlatform.android.kt
@@ -0,0 +1,17 @@
+package com.codandotv.streamplayerapp.core_shared_ui.utils
+
+import android.content.pm.PackageManager
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.LocalContext
+import com.codandotv.streamplayerapp.core_shared_ui.extension.getPackageInfoCompat
+
+@Composable
+actual fun isPackageInstalled(packageName: String): Boolean {
+ val pm = LocalContext.current.packageManager
+ return try {
+ pm.getPackageInfoCompat(packageName)
+ true
+ } catch (e: PackageManager.NameNotFoundException) {
+ false
+ }
+}
\ No newline at end of file
diff --git a/core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.kt b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.android.kt
similarity index 91%
rename from core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.kt
rename to core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.android.kt
index 3013210d..56986e93 100644
--- a/core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.kt
+++ b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponent.android.kt
@@ -13,14 +13,13 @@ 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) {
+actual fun PlayerComponentPlatform(videoId: String, modifier: Modifier) {
val context = LocalContext.current
@@ -93,13 +92,4 @@ fun PlayerComponent(videoId: String, modifier: Modifier = Modifier) {
onDispose { youtubePlayerView.release() }
},
)
-}
-
-@Composable
-@ThemePreviews
-fun PlayerComponentPreview() {
- PlayerComponent(
- videoId = "BigBuckBunny.mp4",
- modifier = Modifier.fillMaxWidth()
- )
-}
+}
\ No newline at end of file
diff --git a/core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/widget/SharingStreamCustomView.kt b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/SharingStreamPlatform.android.kt
similarity index 78%
rename from core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/widget/SharingStreamCustomView.kt
rename to core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/SharingStreamPlatform.android.kt
index b3063630..88a4e83b 100644
--- a/core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/widget/SharingStreamCustomView.kt
+++ b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/SharingStreamPlatform.android.kt
@@ -1,6 +1,5 @@
package com.codandotv.streamplayerapp.core_shared_ui.widget
-import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.ClipData
import android.content.ClipboardManager
@@ -33,6 +32,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
+import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
@@ -42,35 +42,45 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.content.ContextCompat
-import com.codandotv.streamplayerapp.core.shared.ui.R
-import com.codandotv.streamplayerapp.core_shared.extension.getUriFromUrlImage
import com.codandotv.streamplayerapp.core_shared_ui.resources.Colors
import com.codandotv.streamplayerapp.core_shared_ui.utils.Sharing.ANIMATION_DURATION
import com.codandotv.streamplayerapp.core_shared_ui.utils.Sharing.ANIMATION_EXECUTION_DELAY
import com.codandotv.streamplayerapp.core_shared_ui.utils.Sharing.COPY_CONTENT_TYPE_TEXT
-import com.codandotv.streamplayerapp.core_shared_ui.utils.Sharing.INSTAGRAM_PACKAGE_SHARING
-import com.codandotv.streamplayerapp.core_shared_ui.utils.Sharing.INSTAGRAM_STORY_DESTINATION
import com.codandotv.streamplayerapp.core_shared_ui.utils.Sharing.OPTIONS_TITLE_MESSAGE
-import com.codandotv.streamplayerapp.core_shared_ui.utils.Sharing.SHARING_DATA_TYPE_IMAGE
import com.codandotv.streamplayerapp.core_shared_ui.utils.Sharing.SHARING_DATA_TYPE_TEXT
import com.codandotv.streamplayerapp.core_shared_ui.utils.Sharing.SMS_CONTENT_BODY
import com.codandotv.streamplayerapp.core_shared_ui.utils.Sharing.SMS_CONTENT_TYPE
-import com.codandotv.streamplayerapp.core_shared_ui.utils.Sharing.WHATSAPP_PACKAGE_SHARING
-import com.codandotv.streamplayerapp.core_shared_ui.utils.isPackageInstalled
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
+import org.jetbrains.compose.resources.painterResource
+import org.jetbrains.compose.resources.stringResource
+import streamplayerapp_kmp.core_shared_ui.generated.resources.Res
+import streamplayerapp_kmp.core_shared_ui.generated.resources.ic_close
+import streamplayerapp_kmp.core_shared_ui.generated.resources.ic_copy_content
+import streamplayerapp_kmp.core_shared_ui.generated.resources.ic_instagram
+import streamplayerapp_kmp.core_shared_ui.generated.resources.ic_message
+import streamplayerapp_kmp.core_shared_ui.generated.resources.ic_whatsapp
+import streamplayerapp_kmp.core_shared_ui.generated.resources.instagram_not_installed_message
+import streamplayerapp_kmp.core_shared_ui.generated.resources.sharing_link_copied_message
+import streamplayerapp_kmp.core_shared_ui.generated.resources.sharing_title_instagram
+import streamplayerapp_kmp.core_shared_ui.generated.resources.sharing_title_link
+import streamplayerapp_kmp.core_shared_ui.generated.resources.sharing_title_message
+import streamplayerapp_kmp.core_shared_ui.generated.resources.sharing_title_more_options
+import streamplayerapp_kmp.core_shared_ui.generated.resources.sharing_title_sms
+import streamplayerapp_kmp.core_shared_ui.generated.resources.sharing_title_whatsapp
+import streamplayerapp_kmp.core_shared_ui.generated.resources.sharing_whatsapp_message
+import streamplayerapp_kmp.core_shared_ui.generated.resources.sms_app_error_message
+import streamplayerapp_kmp.core_shared_ui.generated.resources.whatsapp_not_installed_message
-@Suppress("LongMethod")
@Composable
-fun SharingStreamCustomView(
+actual fun SharingStreamPlatform(
+ modifier: Modifier,
contentTitle: String,
contentUrl: String,
setShowDialog: (Boolean) -> Unit
@@ -80,12 +90,12 @@ fun SharingStreamCustomView(
val animateTrigger = remember { mutableStateOf(false) }
val context = LocalContext.current
- val linkCopiedMessage = stringResource(id = R.string.sharing_link_copied_message)
+ val linkCopiedMessage = stringResource(Res.string.sharing_link_copied_message)
val contentMessage =
- stringResource(id = R.string.sharing_whatsapp_message, contentTitle, contentUrl)
- val whatsAppNotInstalledMessage = stringResource(id = R.string.whatsapp_not_installed_message)
- val instagramNotInstalledMessage = stringResource(id = R.string.instagram_not_installed_message)
- val smsErrorMessage = stringResource(id = R.string.sms_app_error_message)
+ stringResource(Res.string.sharing_whatsapp_message, contentTitle, contentUrl)
+ val whatsAppNotInstalledMessage = stringResource(Res.string.whatsapp_not_installed_message)
+ val instagramNotInstalledMessage = stringResource(Res.string.instagram_not_installed_message)
+ val smsErrorMessage = stringResource(Res.string.sms_app_error_message)
LaunchedEffect(key1 = Unit) {
launch {
@@ -106,7 +116,7 @@ fun SharingStreamCustomView(
) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text(
- text = stringResource(id = R.string.sharing_title_message),
+ text = stringResource(Res.string.sharing_title_message),
style = TextStyle(
fontSize = 16.sp,
fontFamily = FontFamily.Default,
@@ -130,7 +140,7 @@ fun SharingStreamCustomView(
}
) {
Image(
- painter = painterResource(id = R.drawable.ic_whatsapp),
+ painter = painterResource(Res.drawable.ic_whatsapp),
contentDescription = null,
modifier = Modifier
.width(24.dp)
@@ -138,7 +148,7 @@ fun SharingStreamCustomView(
)
Spacer(modifier = Modifier.width(8.dp))
Text(
- text = stringResource(id = R.string.sharing_title_whatsapp),
+ text = stringResource(Res.string.sharing_title_whatsapp),
style = TextStyle(
fontSize = 18.sp,
fontFamily = FontFamily.Default,
@@ -163,7 +173,7 @@ fun SharingStreamCustomView(
}
) {
Image(
- painter = painterResource(id = R.drawable.ic_message),
+ painter = painterResource(Res.drawable.ic_message),
contentDescription = null,
modifier = Modifier
.width(24.dp)
@@ -171,7 +181,7 @@ fun SharingStreamCustomView(
)
Spacer(modifier = Modifier.width(8.dp))
Text(
- text = stringResource(id = R.string.sharing_title_sms),
+ text = stringResource(Res.string.sharing_title_sms),
style = TextStyle(
fontSize = 18.sp,
fontFamily = FontFamily.Default,
@@ -192,7 +202,7 @@ fun SharingStreamCustomView(
}
) {
Image(
- painter = painterResource(id = R.drawable.ic_instagram),
+ painter = painterResource(Res.drawable.ic_instagram),
contentDescription = null,
modifier = Modifier
.width(24.dp)
@@ -200,7 +210,7 @@ fun SharingStreamCustomView(
)
Spacer(modifier = Modifier.width(8.dp))
Text(
- text = stringResource(id = R.string.sharing_title_instagram),
+ text = stringResource(Res.string.sharing_title_instagram),
style = TextStyle(
fontSize = 18.sp,
fontFamily = FontFamily.Default,
@@ -221,7 +231,7 @@ fun SharingStreamCustomView(
}
) {
Image(
- painter = painterResource(id = R.drawable.ic_copy_content),
+ painter = painterResource(Res.drawable.ic_copy_content),
contentDescription = null,
modifier = Modifier
.width(28.dp)
@@ -234,7 +244,7 @@ fun SharingStreamCustomView(
)
Spacer(modifier = Modifier.width(8.dp))
Text(
- text = stringResource(id = R.string.sharing_title_link),
+ text = stringResource(Res.string.sharing_title_link),
style = TextStyle(
fontSize = 18.sp,
fontFamily = FontFamily.Default,
@@ -244,7 +254,7 @@ fun SharingStreamCustomView(
}
Spacer(modifier = Modifier.height(20.dp))
Text(
- text = stringResource(id = R.string.sharing_title_more_options),
+ text = stringResource(Res.string.sharing_title_more_options),
style = TextStyle(
fontSize = 18.sp,
fontFamily = FontFamily.Default,
@@ -281,7 +291,7 @@ fun SharingStreamCustomView(
}
) {
Image(
- painter = painterResource(id = R.drawable.ic_close),
+ painter = painterResource(Res.drawable.ic_close),
contentDescription = null,
modifier = Modifier
.width(32.dp)
@@ -306,29 +316,30 @@ private fun shareInstagramStory(
contentUrl: String,
errorMessage: String
) {
- if (isPackageInstalled(WHATSAPP_PACKAGE_SHARING, context)) {
- Thread {
- val imgBitmapUri = getUriFromUrlImage(contentUrl, context)
-
- val storiesIntent = Intent(INSTAGRAM_STORY_DESTINATION)
- storiesIntent.setDataAndType(imgBitmapUri, SHARING_DATA_TYPE_IMAGE)
- storiesIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
- storiesIntent.setPackage(INSTAGRAM_PACKAGE_SHARING)
-
- context.grantUriPermission(
- INSTAGRAM_PACKAGE_SHARING, imgBitmapUri, Intent.FLAG_GRANT_READ_URI_PERMISSION
- )
- (context as Activity).runOnUiThread {
- context.startActivity(storiesIntent)
- }
- }.start()
- } else {
- Toast.makeText(
- context,
- errorMessage,
- Toast.LENGTH_SHORT
- ).show()
- }
+// if (isPackageInstalled(WHATSAPP_PACKAGE_SHARING)) {
+// Thread {
+ //TODO:
+// val imgBitmapUri = getUriFromUrlImage(contentUrl)
+//
+// val storiesIntent = Intent(INSTAGRAM_STORY_DESTINATION)
+// storiesIntent.setDataAndType(imgBitmapUri, SHARING_DATA_TYPE_IMAGE)
+// storiesIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+// storiesIntent.setPackage(INSTAGRAM_PACKAGE_SHARING)
+//
+// context.grantUriPermission(
+// INSTAGRAM_PACKAGE_SHARING, imgBitmapUri, Intent.FLAG_GRANT_READ_URI_PERMISSION
+// )
+// (context as Activity).runOnUiThread {
+// context.startActivity(storiesIntent)
+// }
+// }.start()
+// } else {
+// Toast.makeText(
+// context,
+// errorMessage,
+// Toast.LENGTH_SHORT
+// ).show()
+// }
}
private fun shareWhatsAppMessage(
@@ -336,19 +347,19 @@ private fun shareWhatsAppMessage(
message: String,
errorMessage: String
) {
- if (isPackageInstalled(WHATSAPP_PACKAGE_SHARING, context)) {
- val intent = Intent(Intent.ACTION_SEND)
- intent.type = SHARING_DATA_TYPE_TEXT
- intent.setPackage(WHATSAPP_PACKAGE_SHARING)
- intent.putExtra(Intent.EXTRA_TEXT, message)
- context.startActivity(intent)
- } else {
+// if (isPackageInstalled(WHATSAPP_PACKAGE_SHARING)) {
+// val intent = Intent(Intent.ACTION_SEND)
+// intent.type = SHARING_DATA_TYPE_TEXT
+// intent.setPackage(WHATSAPP_PACKAGE_SHARING)
+// intent.putExtra(Intent.EXTRA_TEXT, message)
+// context.startActivity(intent)
+// } else {
Toast.makeText(
context,
errorMessage,
Toast.LENGTH_SHORT
).show()
- }
+// }
}
private fun copyContentLink(context: Context, linkCopiedMessage: String, contentUrl: String) {
diff --git a/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamPlayerTopBarPreview.kt b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamPlayerTopBarPreview.kt
new file mode 100644
index 00000000..40b01ddb
--- /dev/null
+++ b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamPlayerTopBarPreview.kt
@@ -0,0 +1,24 @@
+package com.codandotv.streamplayerapp.core_shared_ui.widget
+
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.TopAppBarDefaults
+import androidx.compose.material3.rememberTopAppBarState
+import androidx.compose.runtime.Composable
+import com.codandotv.streamplayerapp.core_shared.extension.empty
+import com.codandotv.streamplayerapp.core_shared_ui.theme.ThemePreview
+import com.codandotv.streamplayerapp.core_shared_ui.theme.ThemePreviews
+
+@OptIn(ExperimentalMaterial3Api::class)
+@ThemePreviews
+@Composable
+fun StreamPlayerTopBarPreview() {
+ ThemePreview {
+ StreamPlayerTopBar(
+ scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(
+ rememberTopAppBarState()
+ ),
+ onNavigateProfilePicker = {},
+ onSelectedProfilePicture = String.empty()
+ )
+ }
+}
\ No newline at end of file
diff --git a/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamsCardPreview.kt b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamsCardPreview.kt
new file mode 100644
index 00000000..ae074713
--- /dev/null
+++ b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamsCardPreview.kt
@@ -0,0 +1,17 @@
+package com.codandotv.streamplayerapp.core_shared_ui.widget
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.tooling.preview.Preview
+import com.codandotv.streamplayerapp.core_shared.Url.IMAGE_URL_SIZE_300
+
+@Preview
+@Composable
+fun StreamsCardPreview() {
+ StreamsCard(
+ StreamsCardContent(
+ url = "${IMAGE_URL_SIZE_300}evgwd37VHBJhXvSr88Mrx5riFil.jpg",
+ contentDescription = "Test 1",
+ id = "",
+ )
+ )
+}
\ No newline at end of file
diff --git a/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamsCarouselPreview.kt b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamsCarouselPreview.kt
new file mode 100644
index 00000000..e05cd728
--- /dev/null
+++ b/core-shared-ui/src/androidMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamsCarouselPreview.kt
@@ -0,0 +1,16 @@
+package com.codandotv.streamplayerapp.core_shared_ui.widget
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.tooling.preview.Preview
+import kotlinx.coroutines.flow.emptyFlow
+
+@Composable
+@Preview
+fun StreamsCarouselPreview() {
+ StreamsCarousel(
+ content = StreamsCarouselContent(
+ genreTitle = "Ação",
+ contentList = emptyFlow()
+ )
+ )
+}
\ No newline at end of file
diff --git a/core-shared-ui/src/main/res/drawable/transparent_image.xml b/core-shared-ui/src/androidMain/res/drawable/transparent_image.xml
similarity index 100%
rename from core-shared-ui/src/main/res/drawable/transparent_image.xml
rename to core-shared-ui/src/androidMain/res/drawable/transparent_image.xml
diff --git a/core-shared-ui/src/main/res/mipmap-hdpi/ic_netflix.png b/core-shared-ui/src/androidMain/res/mipmap-hdpi/ic_netflix.png
similarity index 100%
rename from core-shared-ui/src/main/res/mipmap-hdpi/ic_netflix.png
rename to core-shared-ui/src/androidMain/res/mipmap-hdpi/ic_netflix.png
diff --git a/core-shared-ui/src/main/res/mipmap-hdpi/ic_netflix_round.png b/core-shared-ui/src/androidMain/res/mipmap-hdpi/ic_netflix_round.png
similarity index 100%
rename from core-shared-ui/src/main/res/mipmap-hdpi/ic_netflix_round.png
rename to core-shared-ui/src/androidMain/res/mipmap-hdpi/ic_netflix_round.png
diff --git a/core-shared-ui/src/main/res/mipmap-mdpi/ic_netflix.png b/core-shared-ui/src/androidMain/res/mipmap-mdpi/ic_netflix.png
similarity index 100%
rename from core-shared-ui/src/main/res/mipmap-mdpi/ic_netflix.png
rename to core-shared-ui/src/androidMain/res/mipmap-mdpi/ic_netflix.png
diff --git a/core-shared-ui/src/main/res/mipmap-mdpi/ic_netflix_round.png b/core-shared-ui/src/androidMain/res/mipmap-mdpi/ic_netflix_round.png
similarity index 100%
rename from core-shared-ui/src/main/res/mipmap-mdpi/ic_netflix_round.png
rename to core-shared-ui/src/androidMain/res/mipmap-mdpi/ic_netflix_round.png
diff --git a/core-shared-ui/src/main/res/mipmap-xhdpi/ic_netflix.png b/core-shared-ui/src/androidMain/res/mipmap-xhdpi/ic_netflix.png
similarity index 100%
rename from core-shared-ui/src/main/res/mipmap-xhdpi/ic_netflix.png
rename to core-shared-ui/src/androidMain/res/mipmap-xhdpi/ic_netflix.png
diff --git a/core-shared-ui/src/main/res/mipmap-xhdpi/ic_netflix_round.png b/core-shared-ui/src/androidMain/res/mipmap-xhdpi/ic_netflix_round.png
similarity index 100%
rename from core-shared-ui/src/main/res/mipmap-xhdpi/ic_netflix_round.png
rename to core-shared-ui/src/androidMain/res/mipmap-xhdpi/ic_netflix_round.png
diff --git a/core-shared-ui/src/main/res/mipmap-xxhdpi/ic_netflix.png b/core-shared-ui/src/androidMain/res/mipmap-xxhdpi/ic_netflix.png
similarity index 100%
rename from core-shared-ui/src/main/res/mipmap-xxhdpi/ic_netflix.png
rename to core-shared-ui/src/androidMain/res/mipmap-xxhdpi/ic_netflix.png
diff --git a/core-shared-ui/src/main/res/mipmap-xxhdpi/ic_netflix_round.png b/core-shared-ui/src/androidMain/res/mipmap-xxhdpi/ic_netflix_round.png
similarity index 100%
rename from core-shared-ui/src/main/res/mipmap-xxhdpi/ic_netflix_round.png
rename to core-shared-ui/src/androidMain/res/mipmap-xxhdpi/ic_netflix_round.png
diff --git a/core-shared-ui/src/main/res/mipmap-xxxhdpi/ic_netflix.png b/core-shared-ui/src/androidMain/res/mipmap-xxxhdpi/ic_netflix.png
similarity index 100%
rename from core-shared-ui/src/main/res/mipmap-xxxhdpi/ic_netflix.png
rename to core-shared-ui/src/androidMain/res/mipmap-xxxhdpi/ic_netflix.png
diff --git a/core-shared-ui/src/main/res/mipmap-xxxhdpi/ic_netflix_round.png b/core-shared-ui/src/androidMain/res/mipmap-xxxhdpi/ic_netflix_round.png
similarity index 100%
rename from core-shared-ui/src/main/res/mipmap-xxxhdpi/ic_netflix_round.png
rename to core-shared-ui/src/androidMain/res/mipmap-xxxhdpi/ic_netflix_round.png
diff --git a/core-shared-ui/src/main/res/values-v31/themes.xml b/core-shared-ui/src/androidMain/res/values-v31/themes.xml
similarity index 50%
rename from core-shared-ui/src/main/res/values-v31/themes.xml
rename to core-shared-ui/src/androidMain/res/values-v31/themes.xml
index f234904b..d6657630 100644
--- a/core-shared-ui/src/main/res/values-v31/themes.xml
+++ b/core-shared-ui/src/androidMain/res/values-v31/themes.xml
@@ -2,8 +2,9 @@
\ No newline at end of file
diff --git a/core-shared-ui/src/androidMain/res/values/strings.xml b/core-shared-ui/src/androidMain/res/values/strings.xml
new file mode 100644
index 00000000..22f3d553
--- /dev/null
+++ b/core-shared-ui/src/androidMain/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ StreamPlayerApp
+
\ No newline at end of file
diff --git a/core-shared-ui/src/androidMain/res/values/themes.xml b/core-shared-ui/src/androidMain/res/values/themes.xml
new file mode 100644
index 00000000..4dfb4c91
--- /dev/null
+++ b/core-shared-ui/src/androidMain/res/values/themes.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core-shared-ui/src/main/res/drawable/ic_add.xml b/core-shared-ui/src/commonMain/composeResources/drawable/ic_add.xml
similarity index 88%
rename from core-shared-ui/src/main/res/drawable/ic_add.xml
rename to core-shared-ui/src/commonMain/composeResources/drawable/ic_add.xml
index eaf0cd27..7d46aa21 100644
--- a/core-shared-ui/src/main/res/drawable/ic_add.xml
+++ b/core-shared-ui/src/commonMain/composeResources/drawable/ic_add.xml
@@ -5,6 +5,6 @@
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
diff --git a/core-shared-ui/src/main/res/drawable/ic_close.xml b/core-shared-ui/src/commonMain/composeResources/drawable/ic_close.xml
similarity index 54%
rename from core-shared-ui/src/main/res/drawable/ic_close.xml
rename to core-shared-ui/src/commonMain/composeResources/drawable/ic_close.xml
index 844b6b62..6df42aa8 100644
--- a/core-shared-ui/src/main/res/drawable/ic_close.xml
+++ b/core-shared-ui/src/commonMain/composeResources/drawable/ic_close.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/core-shared-ui/src/commonMain/composeResources/drawable/ic_copy_content.xml b/core-shared-ui/src/commonMain/composeResources/drawable/ic_copy_content.xml
new file mode 100644
index 00000000..32b6ed83
--- /dev/null
+++ b/core-shared-ui/src/commonMain/composeResources/drawable/ic_copy_content.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/core-shared-ui/src/main/res/drawable/ic_info.xml b/core-shared-ui/src/commonMain/composeResources/drawable/ic_info.xml
similarity index 96%
rename from core-shared-ui/src/main/res/drawable/ic_info.xml
rename to core-shared-ui/src/commonMain/composeResources/drawable/ic_info.xml
index a85cba3b..75a1da27 100644
--- a/core-shared-ui/src/main/res/drawable/ic_info.xml
+++ b/core-shared-ui/src/commonMain/composeResources/drawable/ic_info.xml
@@ -5,6 +5,6 @@
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
diff --git a/core-shared-ui/src/main/res/drawable/ic_instagram.xml b/core-shared-ui/src/commonMain/composeResources/drawable/ic_instagram.xml
similarity index 100%
rename from core-shared-ui/src/main/res/drawable/ic_instagram.xml
rename to core-shared-ui/src/commonMain/composeResources/drawable/ic_instagram.xml
diff --git a/core-shared-ui/src/main/res/drawable/ic_message.xml b/core-shared-ui/src/commonMain/composeResources/drawable/ic_message.xml
similarity index 100%
rename from core-shared-ui/src/main/res/drawable/ic_message.xml
rename to core-shared-ui/src/commonMain/composeResources/drawable/ic_message.xml
diff --git a/core-shared-ui/src/main/res/drawable/ic_netflix.png b/core-shared-ui/src/commonMain/composeResources/drawable/ic_netflix.png
similarity index 100%
rename from core-shared-ui/src/main/res/drawable/ic_netflix.png
rename to core-shared-ui/src/commonMain/composeResources/drawable/ic_netflix.png
diff --git a/core-shared-ui/src/main/res/drawable/ic_netflix_background.xml b/core-shared-ui/src/commonMain/composeResources/drawable/ic_netflix_background.xml
similarity index 100%
rename from core-shared-ui/src/main/res/drawable/ic_netflix_background.xml
rename to core-shared-ui/src/commonMain/composeResources/drawable/ic_netflix_background.xml
diff --git a/core-shared-ui/src/main/res/drawable/ic_netflix_foreground.xml b/core-shared-ui/src/commonMain/composeResources/drawable/ic_netflix_foreground.xml
similarity index 100%
rename from core-shared-ui/src/main/res/drawable/ic_netflix_foreground.xml
rename to core-shared-ui/src/commonMain/composeResources/drawable/ic_netflix_foreground.xml
diff --git a/core-shared-ui/src/main/res/drawable/ic_play.xml b/core-shared-ui/src/commonMain/composeResources/drawable/ic_play.xml
similarity index 100%
rename from core-shared-ui/src/main/res/drawable/ic_play.xml
rename to core-shared-ui/src/commonMain/composeResources/drawable/ic_play.xml
diff --git a/core-shared-ui/src/main/res/drawable/ic_whatsapp.xml b/core-shared-ui/src/commonMain/composeResources/drawable/ic_whatsapp.xml
similarity index 100%
rename from core-shared-ui/src/main/res/drawable/ic_whatsapp.xml
rename to core-shared-ui/src/commonMain/composeResources/drawable/ic_whatsapp.xml
diff --git a/core-shared-ui/src/main/res/drawable/perfil_fake.png b/core-shared-ui/src/commonMain/composeResources/drawable/perfil_fake.png
similarity index 100%
rename from core-shared-ui/src/main/res/drawable/perfil_fake.png
rename to core-shared-ui/src/commonMain/composeResources/drawable/perfil_fake.png
diff --git a/core-shared-ui/src/commonMain/composeResources/drawable/transparent_image.xml b/core-shared-ui/src/commonMain/composeResources/drawable/transparent_image.xml
new file mode 100644
index 00000000..fa4a79ea
--- /dev/null
+++ b/core-shared-ui/src/commonMain/composeResources/drawable/transparent_image.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/core-shared-ui/src/main/res/values/strings.xml b/core-shared-ui/src/commonMain/composeResources/values/strings.xml
similarity index 77%
rename from core-shared-ui/src/main/res/values/strings.xml
rename to core-shared-ui/src/commonMain/composeResources/values/strings.xml
index 61def186..b4a573fa 100644
--- a/core-shared-ui/src/main/res/values/strings.xml
+++ b/core-shared-ui/src/commonMain/composeResources/values/strings.xml
@@ -24,4 +24,12 @@
Preview
+
+ Ícone Netflix
+ Ícone Perfil
+ Ícone Buscar
+ Ícone Fechar
+ Ícone Microfone
+ Ícone Voltar
+ Ícone Projetar
\ No newline at end of file
diff --git a/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/extension/ErrorExtPlatform.kt b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/extension/ErrorExtPlatform.kt
new file mode 100644
index 00000000..d4884c7e
--- /dev/null
+++ b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/extension/ErrorExtPlatform.kt
@@ -0,0 +1,6 @@
+package com.codandotv.streamplayerapp.core_shared_ui.extension
+
+import androidx.compose.runtime.Composable
+
+@Composable
+expect fun ShowErrorMessage(errorMessage: String)
\ No newline at end of file
diff --git a/core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/resources/Colors.kt b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/resources/Colors.kt
similarity index 100%
rename from core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/resources/Colors.kt
rename to core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/resources/Colors.kt
diff --git a/core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/theme/StreamPlayerTheme.kt b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/theme/StreamPlayerTheme.kt
similarity index 100%
rename from core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/theme/StreamPlayerTheme.kt
rename to core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/theme/StreamPlayerTheme.kt
diff --git a/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/utils/Sharing.kt b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/utils/Sharing.kt
new file mode 100644
index 00000000..0a53109c
--- /dev/null
+++ b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/utils/Sharing.kt
@@ -0,0 +1,15 @@
+package com.codandotv.streamplayerapp.core_shared_ui.utils
+
+object Sharing {
+ const val SHARING_DATA_TYPE_TEXT = "text/plain"
+ const val SHARING_DATA_TYPE_IMAGE = "image/*"
+ const val COPY_CONTENT_TYPE_TEXT = "text"
+ const val WHATSAPP_PACKAGE_SHARING = "com.whatsapp"
+ const val INSTAGRAM_PACKAGE_SHARING = "com.instagram.android"
+ const val INSTAGRAM_STORY_DESTINATION = "com.instagram.share.ADD_TO_STORY"
+ const val SMS_CONTENT_TYPE = "sms:"
+ const val SMS_CONTENT_BODY = "sms_body"
+ const val OPTIONS_TITLE_MESSAGE = "Compartilhar usando"
+ const val ANIMATION_EXECUTION_DELAY = 100L
+ const val ANIMATION_DURATION = 300
+}
\ No newline at end of file
diff --git a/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/utils/SharingPlatform.kt b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/utils/SharingPlatform.kt
new file mode 100644
index 00000000..f69166c8
--- /dev/null
+++ b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/utils/SharingPlatform.kt
@@ -0,0 +1,7 @@
+package com.codandotv.streamplayerapp.core_shared_ui.utils
+
+import androidx.compose.runtime.Composable
+
+
+@Composable
+expect fun isPackageInstalled(packageName: String) : Boolean
\ No newline at end of file
diff --git a/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/CloseButton.kt b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/CloseButton.kt
new file mode 100644
index 00000000..02993088
--- /dev/null
+++ b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/CloseButton.kt
@@ -0,0 +1,19 @@
+package com.codandotv.streamplayerapp.core_shared_ui.widget
+
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Close
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.graphics.Color
+import org.jetbrains.compose.resources.stringResource
+import streamplayerapp_kmp.core_shared_ui.generated.resources.Res
+import streamplayerapp_kmp.core_shared_ui.generated.resources.icon_close
+
+@Composable
+fun CloseButton(action: () -> Unit = {}) {
+ DefaultIcon(
+ searchIcon = Icons.Default.Close,
+ contentDescription = stringResource(Res.string.icon_close),
+ onIconClickAction = action,
+ iconColor = Color.Gray
+ )
+}
diff --git a/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/DefaultIcon.kt b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/DefaultIcon.kt
new file mode 100644
index 00000000..8ec6b8d2
--- /dev/null
+++ b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/DefaultIcon.kt
@@ -0,0 +1,30 @@
+package com.codandotv.streamplayerapp.core_shared_ui.widget
+
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Search
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.vector.ImageVector
+
+@Composable
+fun DefaultIcon(
+ modifier: Modifier = Modifier,
+ searchIcon: ImageVector = Icons.Default.Search,
+ iconColor: Color = Color.White,
+ contentDescription: String = "",
+ onIconClickAction: () -> Unit = {}
+) {
+ IconButton(
+ modifier = modifier,
+ onClick = onIconClickAction
+ ) {
+ Icon(
+ imageVector = searchIcon,
+ contentDescription = contentDescription,
+ tint = iconColor
+ )
+ }
+}
diff --git a/core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/widget/IconWithText.kt b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/IconWithText.kt
similarity index 100%
rename from core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/widget/IconWithText.kt
rename to core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/IconWithText.kt
diff --git a/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/MicButton.kt b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/MicButton.kt
new file mode 100644
index 00000000..53b1f4ea
--- /dev/null
+++ b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/MicButton.kt
@@ -0,0 +1,19 @@
+package com.codandotv.streamplayerapp.core_shared_ui.widget
+
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Check
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.graphics.Color
+import org.jetbrains.compose.resources.stringResource
+import streamplayerapp_kmp.core_shared_ui.generated.resources.Res
+import streamplayerapp_kmp.core_shared_ui.generated.resources.icon_mic
+
+@Composable
+fun MicButton(action: () -> Unit = {}) {
+ DefaultIcon(
+ searchIcon = Icons.Default.Check,
+ contentDescription = stringResource(Res.string.icon_mic),
+ onIconClickAction = action,
+ iconColor = Color.Gray
+ )
+}
\ No newline at end of file
diff --git a/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponentPlatform.kt b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponentPlatform.kt
new file mode 100644
index 00000000..18dcb366
--- /dev/null
+++ b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponentPlatform.kt
@@ -0,0 +1,10 @@
+@file:Suppress("EXPECT_AND_ACTUAL_IN_THE_SAME_MODULE")
+
+package com.codandotv.streamplayerapp.core_shared_ui.widget
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+
+@Composable
+expect fun PlayerComponentPlatform(videoId: String, modifier: Modifier = Modifier)
+
diff --git a/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/SearchIcon.kt b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/SearchIcon.kt
new file mode 100644
index 00000000..c92c7987
--- /dev/null
+++ b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/SearchIcon.kt
@@ -0,0 +1,19 @@
+package com.codandotv.streamplayerapp.core_shared_ui.widget
+
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Search
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.graphics.Color
+import org.jetbrains.compose.resources.stringResource
+import streamplayerapp_kmp.core_shared_ui.generated.resources.Res
+import streamplayerapp_kmp.core_shared_ui.generated.resources.icon_search
+
+@Composable
+fun SearchIcon(action: () -> Unit = {}) {
+ DefaultIcon(
+ searchIcon = Icons.Filled.Search,
+ contentDescription = stringResource(Res.string.icon_search),
+ onIconClickAction = action,
+ iconColor = Color.Gray
+ )
+}
\ No newline at end of file
diff --git a/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/SharingStreamPlatform.kt b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/SharingStreamPlatform.kt
new file mode 100644
index 00000000..23ac5f44
--- /dev/null
+++ b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/SharingStreamPlatform.kt
@@ -0,0 +1,12 @@
+package com.codandotv.streamplayerapp.core_shared_ui.widget
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+
+@Composable
+expect fun SharingStreamPlatform(
+ modifier : Modifier = Modifier,
+ contentTitle: String,
+ contentUrl: String,
+ setShowDialog: (Boolean) -> Unit
+)
\ No newline at end of file
diff --git a/core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamPlayerTopBar.kt b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamPlayerTopBar.kt
similarity index 73%
rename from core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamPlayerTopBar.kt
rename to core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamPlayerTopBar.kt
index 0b51a8db..062251f8 100644
--- a/core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamPlayerTopBar.kt
+++ b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamPlayerTopBar.kt
@@ -19,20 +19,24 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior
-import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
-import coil.compose.AsyncImage
-import com.codandotv.streamplayerapp.core.shared.ui.R
-import com.codandotv.streamplayerapp.core_shared.extension.empty
+import coil3.compose.AsyncImage
import com.codandotv.streamplayerapp.core_shared_ui.resources.Colors
-import com.codandotv.streamplayerapp.core_shared_ui.theme.ThemePreview
-import com.codandotv.streamplayerapp.core_shared_ui.theme.ThemePreviews
+import org.jetbrains.compose.resources.painterResource
+import org.jetbrains.compose.resources.stringResource
+import streamplayerapp_kmp.core_shared_ui.generated.resources.Res
+import streamplayerapp_kmp.core_shared_ui.generated.resources.ic_netflix
+import streamplayerapp_kmp.core_shared_ui.generated.resources.icon_netflix
+import streamplayerapp_kmp.core_shared_ui.generated.resources.icon_profile
+import streamplayerapp_kmp.core_shared_ui.generated.resources.icon_search
+import streamplayerapp_kmp.core_shared_ui.generated.resources.perfil_fake
+import streamplayerapp_kmp.core_shared_ui.generated.resources.topbar_categories
+import streamplayerapp_kmp.core_shared_ui.generated.resources.topbar_movies
+import streamplayerapp_kmp.core_shared_ui.generated.resources.topbar_shows
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -69,8 +73,8 @@ private fun StreamPlayerTopBar(
onClick = { /* todo */ }
) {
Icon(
- painter = painterResource(R.drawable.ic_netflix),
- contentDescription = stringResource(id = R.string.icon_netflix),
+ painter = painterResource(Res.drawable.ic_netflix),
+ contentDescription = stringResource(Res.string.icon_netflix),
tint = Color.Unspecified,
)
}
@@ -84,7 +88,7 @@ private fun StreamPlayerTopBar(
) {
Icon(
imageVector = Icons.Default.Search,
- contentDescription = stringResource(id = R.string.icon_search),
+ contentDescription = stringResource(Res.string.icon_search),
tint = Color.White,
)
}
@@ -98,9 +102,9 @@ private fun StreamPlayerTopBar(
.height(24.dp)
.clip(RoundedCornerShape(4.dp)),
model = profilePicture,
- error = painterResource(id = R.drawable.perfil_fake),
- placeholder = painterResource(id = R.drawable.perfil_fake),
- contentDescription = stringResource(id = R.string.icon_profile)
+ error = painterResource(Res.drawable.perfil_fake),
+ placeholder = painterResource(Res.drawable.perfil_fake),
+ contentDescription = stringResource(Res.string.icon_profile)
)
}
}
@@ -120,36 +124,21 @@ private fun StreamPlayerOptionsTopBar(modifier: Modifier, scrollBehavior: TopApp
modifier = Modifier.padding(horizontal = 40.dp)
) {
Text(
- text = stringResource(id = R.string.topbar_shows),
+ text = stringResource(Res.string.topbar_shows),
modifier = Modifier.weight(1f),
color = Color.White
)
Text(
- text = stringResource(id = R.string.topbar_movies),
+ text = stringResource(Res.string.topbar_movies),
modifier = Modifier.weight(1f),
color = Color.White
)
Text(
- text = stringResource(id = R.string.topbar_categories),
+ text = stringResource(Res.string.topbar_categories),
modifier = Modifier.weight(1f),
color = Color.White
)
}
}, colors = TopAppBarDefaults.topAppBarColors(containerColor = Color.Transparent)
)
-}
-
-@OptIn(ExperimentalMaterial3Api::class)
-@ThemePreviews
-@Composable
-fun StreamPlayerTopBarPreview() {
- ThemePreview {
- StreamPlayerTopBar(
- scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior(
- rememberTopAppBarState()
- ),
- onNavigateProfilePicker = {},
- onSelectedProfilePicture = String.empty()
- )
- }
}
\ No newline at end of file
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/widgets/StreamsCard.kt b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamsCard.kt
similarity index 68%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/widgets/StreamsCard.kt
rename to core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamsCard.kt
index e58661be..e52ef1b4 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/widgets/StreamsCard.kt
+++ b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamsCard.kt
@@ -1,6 +1,5 @@
-package com.codandotv.streamplayerapp.feature_list_streams.list.presentation.widgets
+package com.codandotv.streamplayerapp.core_shared_ui.widget
-import android.os.Parcelable
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
@@ -10,11 +9,8 @@ import androidx.compose.material3.Card
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
-import coil.compose.AsyncImage
-import com.codandotv.streamplayerapp.core_networking.Url.IMAGE_URL_SIZE_300
-import kotlinx.parcelize.Parcelize
+import coil3.compose.AsyncImage
@Composable
fun StreamsCard(
@@ -44,21 +40,8 @@ fun StreamsCard(
}
}
-@Parcelize
data class StreamsCardContent(
val id: String,
val url: String,
val contentDescription: String,
-) : Parcelable
-
-@Preview
-@Composable
-fun StreamsCardPreview() {
- StreamsCard(
- StreamsCardContent(
- url = "${IMAGE_URL_SIZE_300}evgwd37VHBJhXvSr88Mrx5riFil.jpg",
- contentDescription = "Test 1",
- id = "",
- )
- )
-}
\ No newline at end of file
+)
\ No newline at end of file
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/widgets/StreamsCarousel.kt b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamsCarousel.kt
similarity index 86%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/widgets/StreamsCarousel.kt
rename to core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamsCarousel.kt
index 61b5e89f..fb47bacd 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/widgets/StreamsCarousel.kt
+++ b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/StreamsCarousel.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp.feature_list_streams.list.presentation.widgets
+package com.codandotv.streamplayerapp.core_shared_ui.widget
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
@@ -12,7 +12,6 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
-import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.paging.PagingData
@@ -69,14 +68,3 @@ data class StreamsCarouselContent(
val genreTitle: String,
val contentList: Flow>
)
-
-@Composable
-@Preview
-fun StreamsCarouselPreview() {
- StreamsCarousel(
- content = StreamsCarouselContent(
- genreTitle = "Ação",
- contentList = emptyFlow()
- )
- )
-}
\ No newline at end of file
diff --git a/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/WebImage.kt b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/WebImage.kt
new file mode 100644
index 00000000..18282996
--- /dev/null
+++ b/core-shared-ui/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/WebImage.kt
@@ -0,0 +1,58 @@
+package com.codandotv.streamplayerapp.core_shared_ui.widget
+
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.heightIn
+import androidx.compose.foundation.layout.widthIn
+import androidx.compose.material3.CircularProgressIndicator
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.FilterQuality
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.unit.dp
+import coil3.compose.LocalPlatformContext
+import coil3.compose.SubcomposeAsyncImage
+import coil3.network.ktor3.KtorNetworkFetcherFactory
+import coil3.request.ImageRequest
+
+@Composable
+fun WebImage(
+ imageUrl: String,
+ contentDescription: String?,
+ contentScale: ContentScale,
+ onFailure: (@Composable () -> Unit) = {},
+ filterQuality: FilterQuality = FilterQuality.High,
+ modifier: Modifier = Modifier
+) {
+ val platformContext = LocalPlatformContext.current
+ val imageRequest = remember {
+ ImageRequest.Builder(
+ context = platformContext
+ ).data(
+ imageUrl
+ ).fetcherFactory(
+ KtorNetworkFetcherFactory()
+ ).build()
+ }
+
+ SubcomposeAsyncImage(
+ model = imageRequest,
+ filterQuality = filterQuality,
+ contentDescription = contentDescription,
+ contentScale = contentScale,
+ modifier = modifier,
+ loading = {
+ Box {
+ CircularProgressIndicator(
+ modifier = Modifier.align(Alignment.Center)
+ .heightIn(max = 52.dp)
+ .widthIn(max = 52.dp)
+ )
+ }
+ },
+ error = {
+ onFailure()
+ }
+ )
+}
\ No newline at end of file
diff --git a/core-shared-ui/src/iosMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/extension/ErrorExtPlatform.ios.kt b/core-shared-ui/src/iosMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/extension/ErrorExtPlatform.ios.kt
new file mode 100644
index 00000000..fc9f5e50
--- /dev/null
+++ b/core-shared-ui/src/iosMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/extension/ErrorExtPlatform.ios.kt
@@ -0,0 +1,7 @@
+package com.codandotv.streamplayerapp.core_shared_ui.extension
+
+import androidx.compose.runtime.Composable
+
+@Composable
+actual fun ShowErrorMessage(errorMessage: String) {
+}
\ No newline at end of file
diff --git a/core-shared-ui/src/iosMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/utils/SharingPlatform.ios.kt b/core-shared-ui/src/iosMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/utils/SharingPlatform.ios.kt
new file mode 100644
index 00000000..abf58cee
--- /dev/null
+++ b/core-shared-ui/src/iosMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/utils/SharingPlatform.ios.kt
@@ -0,0 +1,9 @@
+package com.codandotv.streamplayerapp.core_shared_ui.utils
+
+import androidx.compose.runtime.Composable
+
+@Composable
+actual fun isPackageInstalled(packageName: String): Boolean {
+ //TODO:
+ return false
+}
\ No newline at end of file
diff --git a/core-shared-ui/src/iosMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponentPlatform.ios.kt b/core-shared-ui/src/iosMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponentPlatform.ios.kt
new file mode 100644
index 00000000..9d06f243
--- /dev/null
+++ b/core-shared-ui/src/iosMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/PlayerComponentPlatform.ios.kt
@@ -0,0 +1,7 @@
+package com.codandotv.streamplayerapp.core_shared_ui.widget
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+
+@Composable
+actual fun PlayerComponentPlatform(videoId: String, modifier: Modifier) = Unit
\ No newline at end of file
diff --git a/core-shared-ui/src/iosMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/SharingStreamPlatform.ios.kt b/core-shared-ui/src/iosMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/SharingStreamPlatform.ios.kt
new file mode 100644
index 00000000..25cf421f
--- /dev/null
+++ b/core-shared-ui/src/iosMain/kotlin/com/codandotv/streamplayerapp/core_shared_ui/widget/SharingStreamPlatform.ios.kt
@@ -0,0 +1,13 @@
+package com.codandotv.streamplayerapp.core_shared_ui.widget
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+
+@Composable
+actual fun SharingStreamPlatform(
+ modifier: Modifier,
+ contentTitle: String,
+ contentUrl: String,
+ setShowDialog: (Boolean) -> Unit
+) {
+}
\ No newline at end of file
diff --git a/core-shared-ui/src/main/AndroidManifest.xml b/core-shared-ui/src/main/AndroidManifest.xml
deleted file mode 100644
index ee784d7a..00000000
--- a/core-shared-ui/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/utils/Sharing.kt b/core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/utils/Sharing.kt
deleted file mode 100644
index d7963573..00000000
--- a/core-shared-ui/src/main/java/com/codandotv/streamplayerapp/core_shared_ui/utils/Sharing.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-package com.codandotv.streamplayerapp.core_shared_ui.utils
-
-import android.content.Context
-import android.content.pm.PackageInfo
-import android.content.pm.PackageManager
-import android.os.Build
-
-object Sharing {
-
- const val SHARING_DATA_TYPE_TEXT = "text/plain"
- const val SHARING_DATA_TYPE_IMAGE = "image/*"
- const val COPY_CONTENT_TYPE_TEXT = "text"
- const val WHATSAPP_PACKAGE_SHARING = "com.whatsapp"
- const val INSTAGRAM_PACKAGE_SHARING = "com.instagram.android"
- const val INSTAGRAM_STORY_DESTINATION = "com.instagram.share.ADD_TO_STORY"
- const val SMS_CONTENT_TYPE = "sms:"
- const val SMS_CONTENT_BODY = "sms_body"
- const val OPTIONS_TITLE_MESSAGE = "Compartilhar usando"
- const val ANIMATION_EXECUTION_DELAY = 100L
- const val ANIMATION_DURATION = 300
-}
-
-@Suppress("SwallowedException")
-fun isPackageInstalled(packageName: String, context: Context): Boolean {
- val pm = context.packageManager
- return try {
- pm.getPackageInfoCompat(packageName)
- true
- } catch (e: PackageManager.NameNotFoundException) {
- false
- }
-}
-
-fun PackageManager.getPackageInfoCompat(packageName: String, flags: Int = 0): PackageInfo =
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
- getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(flags.toLong()))
- } else {
- @Suppress("DEPRECATION") getPackageInfo(packageName, flags)
- }
\ No newline at end of file
diff --git a/core-shared-ui/src/main/res/drawable/ic_copy_content.xml b/core-shared-ui/src/main/res/drawable/ic_copy_content.xml
deleted file mode 100644
index 9b16f48a..00000000
--- a/core-shared-ui/src/main/res/drawable/ic_copy_content.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
diff --git a/core-shared-ui/src/main/res/mipmap-anydpi-v26/ic_netflix.xml b/core-shared-ui/src/main/res/mipmap-anydpi-v26/ic_netflix.xml
deleted file mode 100644
index 4cc788ad..00000000
--- a/core-shared-ui/src/main/res/mipmap-anydpi-v26/ic_netflix.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/core-shared-ui/src/main/res/mipmap-anydpi-v26/ic_netflix_round.xml b/core-shared-ui/src/main/res/mipmap-anydpi-v26/ic_netflix_round.xml
deleted file mode 100644
index 4cc788ad..00000000
--- a/core-shared-ui/src/main/res/mipmap-anydpi-v26/ic_netflix_round.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/core-shared-ui/src/main/res/raw/logo.json b/core-shared-ui/src/main/res/raw/logo.json
deleted file mode 100644
index 11491082..00000000
--- a/core-shared-ui/src/main/res/raw/logo.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.5.7","meta":{"g":"LottieFiles AE 0.1.21","a":"","k":"","d":"","tc":"#FFFFFF"},"fr":60,"ip":0,"op":306,"w":512,"h":512,"nm":"Nettflix","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Big N 1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":18,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":28.666,"s":[100]},{"i":{"x":[1],"y":[1]},"o":{"x":[0.612],"y":[0]},"t":114,"s":[100]},{"t":142,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.455,"y":1},"o":{"x":0.684,"y":0},"t":104,"s":[256,256,0],"to":[-24.667,0,0],"ti":[24.667,0,0]},{"t":154.74609375,"s":[108,256,0]}],"ix":2},"a":{"a":0,"k":[0.209,0.143,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.461,0.461,0.667],"y":[1,1,1]},"o":{"x":[0.655,0.655,0.333],"y":[0,0,0]},"t":46,"s":[66,66,100]},{"t":104,"s":[21,21,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.252,"y":1},"o":{"x":0.434,"y":0},"t":18,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[42.684,1.078],[0,0]],"v":[[120.607,218.722],[31.805,211.525],[31.977,211.212],[120.318,218.496]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":46,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[42.684,1.078],[0,0]],"v":[[-34.128,-218.21],[-119.9,-218.21],[31.977,211.212],[120.318,218.496]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":124,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[42.684,1.078],[0,0]],"v":[[-34.128,-218.21],[-119.9,-218.21],[31.977,211.212],[120.318,218.496]],"c":true}]},{"t":156,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[44.422,-6.307],[0,0]],"v":[[-47.223,-218.706],[-102.043,-218.706],[41.501,198.117],[102.46,192.802]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.898039215686,0.035294117647,0.078431372549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Big N 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3868,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Big N 2 matte","parent":1,"td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":10.666,"s":[100]},{"i":{"x":[1],"y":[1]},"o":{"x":[0.612],"y":[0]},"t":114,"s":[100]},{"t":142,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[77.223,0,0],"ix":2},"a":{"a":0,"k":[77.223,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.252,"y":1},"o":{"x":0.434,"y":0},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[1.198,0]],"o":[[0,0],[0,0],[-0.901,0],[0,0]],"v":[[34.099,-359.119],[120.288,-359.43],[120.49,-359.888],[33.164,-359.117]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":24,"s":[{"i":[[0,0],[0,0],[0,0],[28.673,0.875]],"o":[[0,0],[0,0],[-28.673,-3.601],[0,0]],"v":[[34.128,-218.21],[120.318,-218.521],[120.318,218.521],[34.128,211.337]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":124,"s":[{"i":[[0,0],[0,0],[0,0],[28.673,0.875]],"o":[[0,0],[0,0],[-28.673,-3.601],[0,0]],"v":[[34.128,-218.21],[120.318,-218.521],[120.318,218.521],[34.128,211.337]],"c":true}]},{"t":156,"s":[{"i":[[0,0],[0,0],[0,0],[28.249,-4.53]],"o":[[0,0],[0,0],[-27.545,1.34],[0,0]],"v":[[48.414,-218.706],[114.365,-217.965],[116.869,194.041],[44.408,201.102]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.694117647059,0.023529411765,0.058823529412,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Big N 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3868,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Big N 1 shadow 2","tt":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":18,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":28.666,"s":[100]},{"i":{"x":[1],"y":[1]},"o":{"x":[0.612],"y":[0]},"t":114,"s":[100]},{"t":142,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.455,"y":1},"o":{"x":0.684,"y":0},"t":104,"s":[256,256,0],"to":[-24.667,0,0],"ti":[24.667,0,0]},{"t":154.74609375,"s":[108,256,0]}],"ix":2},"a":{"a":0,"k":[0.209,0.143,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.461,0.461,0.667],"y":[1,1,1]},"o":{"x":[0.655,0.655,0.333],"y":[0,0,0]},"t":46,"s":[66,66,100]},{"t":104,"s":[21,21,100]}],"ix":6}},"ao":0,"ef":[{"ty":25,"nm":"Drop Shadow","np":8,"mn":"ADBE Drop Shadow","ix":1,"en":1,"ef":[{"ty":2,"nm":"Shadow Color","mn":"ADBE Drop Shadow-0001","ix":1,"v":{"a":0,"k":[0.086274512112,0,0.0074725952,1],"ix":1}},{"ty":0,"nm":"Opacity","mn":"ADBE Drop Shadow-0002","ix":2,"v":{"a":0,"k":178.5,"ix":2}},{"ty":0,"nm":"Direction","mn":"ADBE Drop Shadow-0003","ix":3,"v":{"a":0,"k":0,"ix":3}},{"ty":0,"nm":"Distance","mn":"ADBE Drop Shadow-0004","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Softness","mn":"ADBE Drop Shadow-0005","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":7,"nm":"Shadow Only","mn":"ADBE Drop Shadow-0006","ix":6,"v":{"a":0,"k":0,"ix":6}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.252,"y":1},"o":{"x":0.434,"y":0},"t":18,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[42.684,1.078],[0,0]],"v":[[120.607,218.722],[31.805,211.525],[31.977,211.212],[120.318,218.496]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":46,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[42.684,1.078],[0,0]],"v":[[-34.128,-218.21],[-119.9,-218.21],[31.977,211.212],[120.318,218.496]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":124,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[42.684,1.078],[0,0]],"v":[[-34.128,-218.21],[-119.9,-218.21],[31.977,211.212],[120.318,218.496]],"c":true}]},{"t":156,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[44.422,-6.307],[0,0]],"v":[[-47.223,-218.706],[-102.043,-218.706],[41.501,198.117],[102.46,192.802]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.898039215686,0.035294117647,0.078431372549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Big N 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":0,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3868,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Big N 2","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":10.666,"s":[100]},{"i":{"x":[1],"y":[1]},"o":{"x":[0.612],"y":[0]},"t":114,"s":[100]},{"t":142,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[77.223,0,0],"ix":2},"a":{"a":0,"k":[77.223,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.252,"y":1},"o":{"x":0.434,"y":0},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[1.198,0]],"o":[[0,0],[0,0],[-0.901,0],[0,0]],"v":[[34.099,-359.119],[120.288,-359.43],[120.49,-359.888],[33.164,-359.117]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":24,"s":[{"i":[[0,0],[0,0],[0,0],[28.673,0.875]],"o":[[0,0],[0,0],[-28.673,-3.601],[0,0]],"v":[[34.128,-218.21],[120.318,-218.521],[120.318,218.521],[34.128,211.337]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":124,"s":[{"i":[[0,0],[0,0],[0,0],[28.673,0.875]],"o":[[0,0],[0,0],[-28.673,-3.601],[0,0]],"v":[[34.128,-218.21],[120.318,-218.521],[120.318,218.521],[34.128,211.337]],"c":true}]},{"t":156,"s":[{"i":[[0,0],[0,0],[0,0],[28.249,-4.53]],"o":[[0,0],[0,0],[-27.545,1.34],[0,0]],"v":[[48.414,-218.706],[114.365,-217.965],[116.869,194.041],[44.408,201.102]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.694117647059,0.023529411765,0.058823529412,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Big N 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3868,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Big N 3 matte","parent":1,"td":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":38,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":48.666,"s":[100]},{"i":{"x":[1],"y":[1]},"o":{"x":[0.612],"y":[0]},"t":114,"s":[100]},{"t":142,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-77.223,0,0],"ix":2},"a":{"a":0,"k":[-77.223,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.252,"y":1},"o":{"x":0.434,"y":0},"t":38,"s":[{"i":[[0,0],[0,0],[0,0],[0,1.089]],"o":[[0,0],[0,0],[26.294,0.724],[0,0]],"v":[[-34.128,-218.21],[-120.318,-218.521],[-120.72,-218.979],[-34.705,-218.587]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":60,"s":[{"i":[[0,0],[0,0],[0,0],[-28.673,0.875]],"o":[[0,0],[0,0],[28.673,-3.601],[0,0]],"v":[[-34.128,-218.21],[-120.318,-218.521],[-120.318,218.521],[-34.128,211.337]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":124,"s":[{"i":[[0,0],[0,0],[0,0],[-28.673,0.875]],"o":[[0,0],[0,0],[28.673,-3.601],[0,0]],"v":[[-34.128,-218.21],[-120.318,-218.521],[-120.318,218.521],[-34.128,211.337]],"c":true}]},{"t":156,"s":[{"i":[[0,0],[0,0],[0,0],[-28.758,-0.959]],"o":[[0,0],[0,0],[28.673,-3.601],[0,0]],"v":[[-43.652,-218.74],[-106.032,-218.137],[-106.032,217.33],[-37.7,211.816]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.694117647059,0.023529411765,0.058823529412,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Big N 3","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3868,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Big N 1 shadow","tt":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":18,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":28.666,"s":[100]},{"i":{"x":[1],"y":[1]},"o":{"x":[0.612],"y":[0]},"t":114,"s":[100]},{"t":142,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.455,"y":1},"o":{"x":0.684,"y":0},"t":104,"s":[256,256,0],"to":[-24.667,0,0],"ti":[24.667,0,0]},{"t":154.74609375,"s":[108,256,0]}],"ix":2},"a":{"a":0,"k":[0.209,0.143,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.461,0.461,0.667],"y":[1,1,1]},"o":{"x":[0.655,0.655,0.333],"y":[0,0,0]},"t":46,"s":[66,66,100]},{"t":104,"s":[21,21,100]}],"ix":6}},"ao":0,"ef":[{"ty":25,"nm":"Drop Shadow","np":8,"mn":"ADBE Drop Shadow","ix":1,"en":1,"ef":[{"ty":2,"nm":"Shadow Color","mn":"ADBE Drop Shadow-0001","ix":1,"v":{"a":0,"k":[0.086274512112,0,0.0074725952,1],"ix":1}},{"ty":0,"nm":"Opacity","mn":"ADBE Drop Shadow-0002","ix":2,"v":{"a":0,"k":178.5,"ix":2}},{"ty":0,"nm":"Direction","mn":"ADBE Drop Shadow-0003","ix":3,"v":{"a":0,"k":0,"ix":3}},{"ty":0,"nm":"Distance","mn":"ADBE Drop Shadow-0004","ix":4,"v":{"a":0,"k":0,"ix":4}},{"ty":0,"nm":"Softness","mn":"ADBE Drop Shadow-0005","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":7,"nm":"Shadow Only","mn":"ADBE Drop Shadow-0006","ix":6,"v":{"a":0,"k":0,"ix":6}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.252,"y":1},"o":{"x":0.434,"y":0},"t":18,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[42.684,1.078],[0,0]],"v":[[120.607,218.722],[31.805,211.525],[31.977,211.212],[120.318,218.496]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":46,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[42.684,1.078],[0,0]],"v":[[-34.128,-218.21],[-119.9,-218.21],[31.977,211.212],[120.318,218.496]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":124,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[42.684,1.078],[0,0]],"v":[[-34.128,-218.21],[-119.9,-218.21],[31.977,211.212],[120.318,218.496]],"c":true}]},{"t":156,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[44.422,-6.307],[0,0]],"v":[[-47.223,-218.706],[-102.043,-218.706],[41.501,198.117],[102.46,192.802]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.898039215686,0.035294117647,0.078431372549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Big N 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3868,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Big N 3","parent":1,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":38,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":48.666,"s":[100]},{"i":{"x":[1],"y":[1]},"o":{"x":[0.612],"y":[0]},"t":114,"s":[100]},{"t":142,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-77.223,0,0],"ix":2},"a":{"a":0,"k":[-77.223,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.252,"y":1},"o":{"x":0.434,"y":0},"t":38,"s":[{"i":[[0,0],[0,0],[0,0],[0,1.089]],"o":[[0,0],[0,0],[26.294,0.724],[0,0]],"v":[[-34.128,-218.21],[-120.318,-218.521],[-120.72,-218.979],[-34.705,-218.587]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":60,"s":[{"i":[[0,0],[0,0],[0,0],[-28.673,0.875]],"o":[[0,0],[0,0],[28.673,-3.601],[0,0]],"v":[[-34.128,-218.21],[-120.318,-218.521],[-120.318,218.521],[-34.128,211.337]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":124,"s":[{"i":[[0,0],[0,0],[0,0],[-28.673,0.875]],"o":[[0,0],[0,0],[28.673,-3.601],[0,0]],"v":[[-34.128,-218.21],[-120.318,-218.521],[-120.318,218.521],[-34.128,211.337]],"c":true}]},{"t":156,"s":[{"i":[[0,0],[0,0],[0,0],[-28.758,-0.959]],"o":[[0,0],[0,0],[28.673,-3.601],[0,0]],"v":[[-43.652,-218.74],[-106.032,-218.137],[-106.032,217.33],[-37.7,211.816]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.694117647059,0.023529411765,0.058823529412,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Big N 3","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":3868,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Netflix reveal","parent":9,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.715,"y":1},"o":{"x":0.414,"y":0},"t":206.207,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[166,-55],[165,-52]],"c":false}]},{"t":220,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[164,-51],[125,45.5]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.715,"y":1},"o":{"x":0.414,"y":0},"t":200.297,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[125,-54.5],[125,-52]],"c":false}]},{"t":214.08984375,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[126.5,-52],[164,50]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[144.5,-1],"ix":2},"a":{"a":0,"k":[144.5,-1],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"X","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.715,"y":1},"o":{"x":0.414,"y":0},"t":186.271,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[100,-51],[100,-48]],"c":false}]},{"t":198.09375,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[100,-47],[100,42]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"I","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.715,"y":1},"o":{"x":0.414,"y":0},"t":175.586,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[37,29],[40.5,29]],"c":false}]},{"t":189.37890625,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[37,29],[83.5,28.5]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"L 2","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.715,"y":1},"o":{"x":0.414,"y":0},"t":171.645,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[49,-50.5],[49,-48.5]],"c":true}]},{"t":185.4375,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[49,-47.5],[49.5,38]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"L1","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[60.25,-4.75],"ix":2},"a":{"a":0,"k":[60.25,-4.75],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"L","np":2,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.715,"y":1},"o":{"x":0.414,"y":0},"t":159.992,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-9.5,-7.5],[-11.5,-7.5]],"c":false}]},{"t":175.75390625,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[28,-7.5],[-9.5,-7.5]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.715,"y":1},"o":{"x":0.414,"y":0},"t":154.08,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0.5,-50],[0.5,-48]],"c":false}]},{"t":169.84375,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0.5,-48],[0,37]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 3","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.715,"y":1},"o":{"x":0.414,"y":0},"t":145.266,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-10.5,-39.5],[-12,-39.5]],"c":false}]},{"t":160.693359375,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[36,-39.5],[-9,-39.5]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[13.25,-5.5],"ix":2},"a":{"a":0,"k":[13.25,-5.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"F","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.715,"y":1},"o":{"x":0.414,"y":0},"t":136.115,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-40.5,-54],[-40.5,-49.5]],"c":false}]},{"t":151.876953125,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-38.5,-45.5],[-39,38.5]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.715,"y":1},"o":{"x":0.414,"y":0},"t":132.174,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-62.5,-38.5],[-66,-38.5]],"c":false}]},{"t":147.9375,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-14.5,-40.5],[-63.5,-38.5]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[-39,-3.5],"ix":2},"a":{"a":0,"k":[-39,-3.5],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"T","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.715,"y":1},"o":{"x":0.414,"y":0},"t":127.73,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-114,32.5],[-119,32.5]],"c":false}]},{"t":147.435546875,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-67.5,29],[-112,32.5]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 3","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.715,"y":1},"o":{"x":0.414,"y":0},"t":121.82,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-115,-6.5],[-119.5,-6.5]],"c":true}]},{"t":141.033203125,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-74.5,-6],[-113,-6]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.715,"y":1},"o":{"x":0.414,"y":0},"t":117.881,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-103.5,-54.5],[-103.5,-49]],"c":false}]},{"t":137.58203125,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-103.5,-48.5],[-102.5,42]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 4","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.715,"y":1},"o":{"x":0.414,"y":0},"t":110,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-117,-38],[-120.5,-38]],"c":false}]},{"t":129.2109375,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-68,-38],[-114.5,-38]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[-90,-3.25],"ix":2},"a":{"a":0,"k":[-90,-3.25],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"E","np":4,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false}],"ip":101,"op":3868,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Etflix","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.455],"y":[1]},"o":{"x":[0.684],"y":[0]},"t":104,"s":[402.75]},{"t":154.74609375,"s":[256]}],"ix":3},"y":{"a":0,"k":256,"ix":4}},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-5.131,0],[0,0],[5.401,-0.27],[0,0],[-8.551,0.27],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[5.582,0],[0,0],[-6.392,0],[0,0],[8.462,-0.54],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-95.285,-12.333],[-76.021,-12.603],[-76.021,1.8],[-95.285,2.07],[-95.285,23.495],[-69.81,21.964],[-69.81,35.826],[-109.689,38.978],[-109.689,-46.09],[-69.81,-46.09],[-69.81,-31.687],[-95.285,-31.687]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[4.68,-0.18],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[-4.861,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-16.249,-31.686],[-31.192,-31.686],[-31.192,34.568],[-45.594,34.747],[-45.594,-31.686],[-60.537,-31.686],[-60.537,-46.09],[-16.248,-46.09]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[7.156,-13.323],[26.871,-13.323],[26.871,1.08],[7.156,1.08],[7.156,33.757],[-6.978,33.757],[-6.978,-46.09],[33.262,-46.09],[33.262,-31.687],[7.156,-31.687]],"c":true},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":4,"ty":"sh","ix":5,"ks":{"a":0,"k":{"i":[[0,0],[-8.012,-0.449],[0,0],[13.143,0.271],[0,0],[0,0]],"o":[[8.192,0.18],[0,0],[-12.873,-0.811],[0,0],[0,0],[0,0]],"v":[[56.667,21.154],[81.152,22.415],[81.152,36.638],[42.264,34.747],[42.264,-46.09],[56.667,-46.09]],"c":true},"ix":2},"nm":"Path 5","mn":"ADBE Vector Shape - Group","hd":false},{"ind":5,"ty":"sh","ix":6,"ks":{"a":0,"k":{"i":[[0,0],[-4.681,-0.539],[0,0],[0,0]],"o":[[4.591,0.27],[0,0],[0,0],[0,0]],"v":[[93.304,37.628],[107.437,38.708],[107.437,-46.09],[93.304,-46.09]],"c":true},"ix":2},"nm":"Path 6","mn":"ADBE Vector Shape - Group","hd":false},{"ind":6,"ty":"sh","ix":7,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[5.401,0.9],[0,0],[0,0],[5.22,0.72],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[-5.403,-0.72],[0,0],[0,0],[-5.222,-0.901],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[170.541,-46.09],[152.267,-2.25],[170.541,46.09],[154.337,43.479],[143.985,16.834],[133.454,41.319],[117.971,39.428],[136.515,-2.791],[119.771,-46.09],[135.253,-46.09],[144.705,-21.875],[154.788,-46.09]],"c":true},"ix":2},"nm":"Path 7","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.898039215686,0.035294117647,0.078431372549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Netflix Wordmark","np":8,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":102,"op":3868,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Netflix N","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.455],"y":[1]},"o":{"x":[0.684],"y":[0]},"t":104,"s":[402.75]},{"t":154.74609375,"s":[256]}],"ix":3},"y":{"a":0,"k":256,"ix":4}},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[5.401,-0.719],[0,0],[0,0],[4.861,-0.72],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[-5.131,0.901],[0,0],[0,0],[-5.131,0.54],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[-123.641,40.148],[-139.394,42.039],[-155.868,-6.211],[-155.868,44.11],[-170.541,46.09],[-170.541,-46.09],[-156.858,-46.09],[-138.134,6.212],[-138.134,-46.09],[-123.641,-46.09]],"c":true},"ix":2},"nm":"N","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.898039215686,0.035294117647,0.078431372549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Netflix Wordmark","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":102,"op":3868,"st":0,"bm":0}],"markers":[]}
\ No newline at end of file
diff --git a/core-shared-ui/src/main/res/values-night/themes.xml b/core-shared-ui/src/main/res/values-night/themes.xml
deleted file mode 100644
index 04c0b155..00000000
--- a/core-shared-ui/src/main/res/values-night/themes.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
diff --git a/core-shared-ui/src/main/res/values/colors.xml b/core-shared-ui/src/main/res/values/colors.xml
deleted file mode 100644
index f8c6127d..00000000
--- a/core-shared-ui/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- #FFBB86FC
- #FF6200EE
- #FF3700B3
- #FF03DAC5
- #FF018786
- #FF000000
- #FFFFFFFF
-
\ No newline at end of file
diff --git a/core-shared-ui/src/main/res/values/content-description.xml b/core-shared-ui/src/main/res/values/content-description.xml
deleted file mode 100644
index a3353e8e..00000000
--- a/core-shared-ui/src/main/res/values/content-description.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- Ícone Netflix
- Ícone Perfil
- Ícone Buscar
- Ícone Fechar
- Ícone Microfone
- Ícone Voltar
- Ícone Projetar
-
\ No newline at end of file
diff --git a/core-shared-ui/src/main/res/values/themes.xml b/core-shared-ui/src/main/res/values/themes.xml
deleted file mode 100644
index 56f74635..00000000
--- a/core-shared-ui/src/main/res/values/themes.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/core-shared/build.gradle.kts b/core-shared/build.gradle.kts
index f1b45dda..692b2f9a 100644
--- a/core-shared/build.gradle.kts
+++ b/core-shared/build.gradle.kts
@@ -1,7 +1,12 @@
plugins {
- id("com.streamplayer.android-library")
+ id("com.streamplayer.kmp-library")
}
-dependencies {
- implementation(libs.bundles.koin)
+
+kotlin {
+ sourceSets {
+ commonMain.dependencies {
+ implementation(libs.koin.core)
+ }
+ }
}
\ No newline at end of file
diff --git a/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/Url.kt b/core-shared/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared/Url.kt
similarity index 80%
rename from core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/Url.kt
rename to core-shared/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared/Url.kt
index 1b0d9b77..8ea4c8e2 100644
--- a/core-networking/src/main/java/com/codandotv/streamplayerapp/core_networking/Url.kt
+++ b/core-shared/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared/Url.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp.core_networking
+package com.codandotv.streamplayerapp.core_shared
object Url {
const val IMAGE_URL_SIZE_200 = "https://image.tmdb.org/t/p/w200/"
diff --git a/core-shared/src/main/java/com/codandotv/streamplayerapp/core_shared/extension/String.Ext.kt b/core-shared/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared/extension/String.Ext.kt
similarity index 100%
rename from core-shared/src/main/java/com/codandotv/streamplayerapp/core_shared/extension/String.Ext.kt
rename to core-shared/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared/extension/String.Ext.kt
diff --git a/core-shared/src/main/java/com/codandotv/streamplayerapp/core_shared/qualifier/QualifierDispatcherIO.kt b/core-shared/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared/qualifier/QualifierDispatcherIO.kt
similarity index 100%
rename from core-shared/src/main/java/com/codandotv/streamplayerapp/core_shared/qualifier/QualifierDispatcherIO.kt
rename to core-shared/src/commonMain/kotlin/com/codandotv/streamplayerapp/core_shared/qualifier/QualifierDispatcherIO.kt
diff --git a/core-shared/src/main/AndroidManifest.xml b/core-shared/src/main/AndroidManifest.xml
deleted file mode 100644
index a8800291..00000000
--- a/core-shared/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/core-shared/src/main/java/com/codandotv/streamplayerapp/core_shared/extension/ErrorExt.kt b/core-shared/src/main/java/com/codandotv/streamplayerapp/core_shared/extension/ErrorExt.kt
deleted file mode 100644
index 606f8b9d..00000000
--- a/core-shared/src/main/java/com/codandotv/streamplayerapp/core_shared/extension/ErrorExt.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.codandotv.streamplayerapp.core_shared.extension
-
-import android.content.Context
-import android.widget.Toast
-
-fun showErrorMessage(context: Context, errorMessage: String, duration: Int = Toast.LENGTH_LONG) {
- Toast.makeText(context, errorMessage, duration).show()
-}
\ No newline at end of file
diff --git a/core-shared/src/main/java/com/codandotv/streamplayerapp/core_shared/extension/UriExt.kt b/core-shared/src/main/java/com/codandotv/streamplayerapp/core_shared/extension/UriExt.kt
deleted file mode 100644
index 573f734e..00000000
--- a/core-shared/src/main/java/com/codandotv/streamplayerapp/core_shared/extension/UriExt.kt
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.codandotv.streamplayerapp.core_shared.extension
-
-import android.content.Context
-import android.graphics.BitmapFactory
-import android.net.Uri
-import android.provider.MediaStore
-import java.io.IOException
-import java.io.InputStream
-import java.net.HttpURLConnection
-import java.net.MalformedURLException
-import java.net.URL
-import java.util.*
-
-@Suppress("MagicNumber", "SwallowedException")
-fun getUriFromUrlImage(
- contentUrl: String,
- context: Context
-): Uri? {
- var url: URL? = null
- try {
- url = URL(contentUrl)
- } catch (e: MalformedURLException) {
- e.printStackTrace()
- }
- var connection: HttpURLConnection? = null
- try {
- assert(url != null)
- connection = url!!.openConnection() as HttpURLConnection
- } catch (e: IOException) {
- showErrorMessage(context, "Erro ao buscar imagem")
- }
- assert(connection != null)
- connection!!.doInput = true
- try {
- connection.connect()
- } catch (e: IOException) {
- showErrorMessage(context, "Erro ao buscar imagem")
- }
- var input: InputStream? = null
- try {
- input = connection.inputStream
- } catch (e: IOException) {
- showErrorMessage(context, "Erro ao buscar imagem")
- }
- val imgBitmap = BitmapFactory.decodeStream(input)
- val rand = Random()
- val randNo = rand.nextInt(100000)
- val imgBitmapPath = MediaStore.Images.Media.insertImage(
- context.contentResolver, imgBitmap,
- "IMG:$randNo", null
- )
- return Uri.parse(imgBitmapPath)
-}
\ No newline at end of file
diff --git a/feature-favorites/.gitignore b/feature-detail/.gitignore
similarity index 100%
rename from feature-favorites/.gitignore
rename to feature-detail/.gitignore
diff --git a/feature-detail/build.gradle.kts b/feature-detail/build.gradle.kts
new file mode 100644
index 00000000..0ad22fc8
--- /dev/null
+++ b/feature-detail/build.gradle.kts
@@ -0,0 +1,38 @@
+@file:Suppress("UnstableApiUsage")
+
+plugins {
+ id("com.streamplayer.kmp-library")
+ alias(libs.plugins.jetbrains.compose)
+ alias(libs.plugins.compose.compiler)
+}
+
+kotlin {
+ sourceSets {
+ androidMain.dependencies {
+ implementation(compose.preview)
+ }
+ commonMain.dependencies {
+ implementation(libs.koin.core)
+ implementation(libs.koin.compose)
+ implementation(libs.koin.compose.viewmodel)
+
+ implementation(projects.coreNetworking)
+ implementation(projects.coreNavigation)
+ implementation(projects.coreShared)
+ implementation(projects.coreSharedUi)
+ implementation(projects.coreLocalStorage)
+
+ implementation(compose.material3)
+ implementation(compose.ui)
+ implementation(compose.components.resources)
+
+ implementation(libs.navigation.compose)
+
+ implementation(libs.ktor.client.content.serialization.json)
+ implementation(libs.ktor.client.content.negotiation)
+ }
+ androidUnitTest.dependencies {
+ implementation(libs.bundles.test)
+ }
+ }
+}
\ No newline at end of file
diff --git a/feature-favorites/consumer-rules.pro b/feature-detail/consumer-rules.pro
similarity index 100%
rename from feature-favorites/consumer-rules.pro
rename to feature-detail/consumer-rules.pro
diff --git a/feature-favorites/proguard-rules.pro b/feature-detail/proguard-rules.pro
similarity index 100%
rename from feature-favorites/proguard-rules.pro
rename to feature-detail/proguard-rules.pro
diff --git a/feature-list-streams/src/test/java/com/codandotv/streamplayerapp/feature_list_streams/detail/DetailStreamRepositoryTest.kt b/feature-detail/src/androidUnitTest/kotlin/com/codandotv/streamplayerapp/feature_detail/DetailStreamRepositoryTest.kt
similarity index 80%
rename from feature-list-streams/src/test/java/com/codandotv/streamplayerapp/feature_list_streams/detail/DetailStreamRepositoryTest.kt
rename to feature-detail/src/androidUnitTest/kotlin/com/codandotv/streamplayerapp/feature_detail/DetailStreamRepositoryTest.kt
index f2f00d88..042fb260 100644
--- a/feature-list-streams/src/test/java/com/codandotv/streamplayerapp/feature_list_streams/detail/DetailStreamRepositoryTest.kt
+++ b/feature-detail/src/androidUnitTest/kotlin/com/codandotv/streamplayerapp/feature_detail/DetailStreamRepositoryTest.kt
@@ -1,10 +1,10 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail
+package com.codandotv.streamplayerapp.feature_detail
import com.codandotv.streamplayerapp.core_local_storage.data.dao.FavoriteDao
import com.codandotv.streamplayerapp.core_networking.handleError.NetworkResponse
-import com.codandotv.streamplayerapp.feature_list_streams.detail.data.DetailStreamRepository
-import com.codandotv.streamplayerapp.feature_list_streams.detail.data.DetailStreamRepositoryImpl
-import com.codandotv.streamplayerapp.feature_list_streams.detail.data.DetailStreamService
+import com.codandotv.streamplayerapp.feature_detail.data.DetailStreamRepository
+import com.codandotv.streamplayerapp.feature_detail.data.DetailStreamRepositoryImpl
+import com.codandotv.streamplayerapp.feature_detail.data.DetailStreamService
import io.mockk.coEvery
import io.mockk.coVerifyOrder
import io.mockk.mockk
diff --git a/feature-list-streams/src/test/java/com/codandotv/streamplayerapp/feature_list_streams/detail/DetailStreamUseCaseTest.kt b/feature-detail/src/androidUnitTest/kotlin/com/codandotv/streamplayerapp/feature_detail/DetailStreamUseCaseTest.kt
similarity index 66%
rename from feature-list-streams/src/test/java/com/codandotv/streamplayerapp/feature_list_streams/detail/DetailStreamUseCaseTest.kt
rename to feature-detail/src/androidUnitTest/kotlin/com/codandotv/streamplayerapp/feature_detail/DetailStreamUseCaseTest.kt
index f08442b4..37e4c128 100644
--- a/feature-list-streams/src/test/java/com/codandotv/streamplayerapp/feature_list_streams/detail/DetailStreamUseCaseTest.kt
+++ b/feature-detail/src/androidUnitTest/kotlin/com/codandotv/streamplayerapp/feature_detail/DetailStreamUseCaseTest.kt
@@ -1,15 +1,12 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail
+package com.codandotv.streamplayerapp.feature_detail
-import com.codandotv.streamplayerapp.feature_list_streams.detail.data.DetailStreamRepository
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.DetailStream
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.DetailStreamUseCase
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.DetailStreamUseCaseImpl
+import com.codandotv.streamplayerapp.feature_detail.data.DetailStreamRepository
+import com.codandotv.streamplayerapp.feature_detail.domain.DetailStreamUseCase
+import com.codandotv.streamplayerapp.feature_detail.domain.DetailStreamUseCaseImpl
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.mockk
-import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
diff --git a/feature-list-streams/src/test/java/com/codandotv/streamplayerapp/feature_list_streams/detail/DetailStreamViewModelTest.kt b/feature-detail/src/androidUnitTest/kotlin/com/codandotv/streamplayerapp/feature_detail/DetailStreamViewModelTest.kt
similarity index 78%
rename from feature-list-streams/src/test/java/com/codandotv/streamplayerapp/feature_list_streams/detail/DetailStreamViewModelTest.kt
rename to feature-detail/src/androidUnitTest/kotlin/com/codandotv/streamplayerapp/feature_detail/DetailStreamViewModelTest.kt
index 60a47271..65a2ae0d 100644
--- a/feature-list-streams/src/test/java/com/codandotv/streamplayerapp/feature_list_streams/detail/DetailStreamViewModelTest.kt
+++ b/feature-detail/src/androidUnitTest/kotlin/com/codandotv/streamplayerapp/feature_detail/DetailStreamViewModelTest.kt
@@ -1,11 +1,10 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail
+package com.codandotv.streamplayerapp.feature_detail
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
-import androidx.lifecycle.LifecycleOwner
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.DetailStreamUseCase
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.VideoStreamsUseCase
-import com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.screens.DetailStreamViewModel
-import com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.screens.DetailStreamsUIState
+import com.codandotv.streamplayerapp.feature_detail.domain.DetailStreamUseCase
+import com.codandotv.streamplayerapp.feature_detail.domain.VideoStreamsUseCase
+import com.codandotv.streamplayerapp.feature_detail.presentation.screens.DetailStreamViewModel
+import com.codandotv.streamplayerapp.feature_detail.presentation.screens.DetailStreamsUIState
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.mockk
diff --git a/feature-list-streams/src/test/java/com/codandotv/streamplayerapp/feature_list_streams/detail/InstantTaskCoroutinesExecutorRule.kt b/feature-detail/src/androidUnitTest/kotlin/com/codandotv/streamplayerapp/feature_detail/InstantTaskCoroutinesExecutorRule.kt
similarity index 91%
rename from feature-list-streams/src/test/java/com/codandotv/streamplayerapp/feature_list_streams/detail/InstantTaskCoroutinesExecutorRule.kt
rename to feature-detail/src/androidUnitTest/kotlin/com/codandotv/streamplayerapp/feature_detail/InstantTaskCoroutinesExecutorRule.kt
index f30e6ca3..f0cf84a7 100644
--- a/feature-list-streams/src/test/java/com/codandotv/streamplayerapp/feature_list_streams/detail/InstantTaskCoroutinesExecutorRule.kt
+++ b/feature-detail/src/androidUnitTest/kotlin/com/codandotv/streamplayerapp/feature_detail/InstantTaskCoroutinesExecutorRule.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail
+package com.codandotv.streamplayerapp.feature_detail
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
diff --git a/feature-list-streams/src/test/java/com/codandotv/streamplayerapp/feature_list_streams/detail/Shared.kt b/feature-detail/src/androidUnitTest/kotlin/com/codandotv/streamplayerapp/feature_detail/Shared.kt
similarity index 64%
rename from feature-list-streams/src/test/java/com/codandotv/streamplayerapp/feature_list_streams/detail/Shared.kt
rename to feature-detail/src/androidUnitTest/kotlin/com/codandotv/streamplayerapp/feature_detail/Shared.kt
index 3adda93e..095ab5dc 100644
--- a/feature-list-streams/src/test/java/com/codandotv/streamplayerapp/feature_list_streams/detail/Shared.kt
+++ b/feature-detail/src/androidUnitTest/kotlin/com/codandotv/streamplayerapp/feature_detail/Shared.kt
@@ -1,8 +1,8 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail
+package com.codandotv.streamplayerapp.feature_detail
-import com.codandotv.streamplayerapp.feature_list_streams.detail.data.model.DetailStreamResponse
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.DetailStream
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.VideoStream
+import com.codandotv.streamplayerapp.feature_detail.data.model.DetailStreamResponse
+import com.codandotv.streamplayerapp.feature_detail.domain.DetailStream
+import com.codandotv.streamplayerapp.feature_detail.domain.VideoStream
val videoStream = VideoStream(
movieId = 123,
@@ -22,7 +22,7 @@ val videosStreamsList = listOf(
)
val detailStreamResponse = DetailStreamResponse(
- id = "id",
+ id = 12,
title = "title",
overview = "overview",
tagline = "tagline",
diff --git a/feature-list-streams/src/main/res/drawable/netflix_detail.webp b/feature-detail/src/commonMain/composeResources/drawable/netflix_detail.webp
similarity index 100%
rename from feature-list-streams/src/main/res/drawable/netflix_detail.webp
rename to feature-detail/src/commonMain/composeResources/drawable/netflix_detail.webp
diff --git a/feature-list-streams/src/main/res/drawable/play_circle.xml b/feature-detail/src/commonMain/composeResources/drawable/play_circle.xml
similarity index 100%
rename from feature-list-streams/src/main/res/drawable/play_circle.xml
rename to feature-detail/src/commonMain/composeResources/drawable/play_circle.xml
diff --git a/feature-detail/src/commonMain/composeResources/values/strings.xml b/feature-detail/src/commonMain/composeResources/values/strings.xml
new file mode 100644
index 00000000..ac85d916
--- /dev/null
+++ b/feature-detail/src/commonMain/composeResources/values/strings.xml
@@ -0,0 +1,12 @@
+
+
+ Assistir
+ Baixar E1
+ Filme
+ Minha Lista
+ Classificar
+ Compartilhar
+ Baixar completo
+ Pesquisar
+ Voltar
+
\ No newline at end of file
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/data/DetailStreamRepository.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/data/DetailStreamRepository.kt
similarity index 75%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/data/DetailStreamRepository.kt
rename to feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/data/DetailStreamRepository.kt
index 7fd6c5e1..21adf8f1 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/data/DetailStreamRepository.kt
+++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/data/DetailStreamRepository.kt
@@ -1,12 +1,12 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail.data
+package com.codandotv.streamplayerapp.feature_detail.data
import com.codandotv.streamplayerapp.core_local_storage.data.dao.FavoriteDao
import com.codandotv.streamplayerapp.core_networking.handleError.toFlow
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.DetailStream
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.VideoStream
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.toDetailStream
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.toDetailStreamLocal
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.toVideoStreams
+import com.codandotv.streamplayerapp.feature_detail.domain.DetailStream
+import com.codandotv.streamplayerapp.feature_detail.domain.VideoStream
+import com.codandotv.streamplayerapp.feature_detail.domain.toDetailStream
+import com.codandotv.streamplayerapp.feature_detail.domain.toDetailStreamLocal
+import com.codandotv.streamplayerapp.feature_detail.domain.toVideoStreams
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
diff --git a/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/data/DetailStreamService.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/data/DetailStreamService.kt
new file mode 100644
index 00000000..f4c69ba1
--- /dev/null
+++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/data/DetailStreamService.kt
@@ -0,0 +1,28 @@
+package com.codandotv.streamplayerapp.feature_detail.data
+
+import com.codandotv.streamplayerapp.core_networking.handleError.NetworkResponse
+import com.codandotv.streamplayerapp.core_networking.handleError.safeRequest
+import com.codandotv.streamplayerapp.feature_detail.data.model.DetailStreamResponse
+import com.codandotv.streamplayerapp.feature_detail.data.model.VideoStreamsResponse
+import io.ktor.client.HttpClient
+import io.ktor.client.request.url
+
+interface DetailStreamService {
+ suspend fun getMovie(movieId: String): NetworkResponse
+ suspend fun getVideoStreams(movieId: String): NetworkResponse
+}
+
+class DetailStreamServiceImpl(
+ private val client: HttpClient
+) : DetailStreamService {
+
+ override suspend fun getMovie(movieId: String): NetworkResponse =
+ client.safeRequest {
+ url("movie/$movieId")
+ }
+
+ override suspend fun getVideoStreams(movieId: String): NetworkResponse =
+ client.safeRequest {
+ url("movie/$movieId/videos")
+ }
+}
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/data/model/DetailStreamResponse.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/data/model/DetailStreamResponse.kt
similarity index 60%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/data/model/DetailStreamResponse.kt
rename to feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/data/model/DetailStreamResponse.kt
index 58f66c52..27c79e86 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/data/model/DetailStreamResponse.kt
+++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/data/model/DetailStreamResponse.kt
@@ -1,8 +1,11 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail.data.model
+package com.codandotv.streamplayerapp.feature_detail.data.model
+import kotlinx.serialization.Serializable
+
+@Serializable
@Suppress("ConstructorParameterNaming")
data class DetailStreamResponse(
- val id : String,
+ val id : Long,
val title : String,
val overview : String,
val tagline : String,
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/data/model/VideoStreamResponse.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/data/model/VideoStreamResponse.kt
similarity index 67%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/data/model/VideoStreamResponse.kt
rename to feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/data/model/VideoStreamResponse.kt
index e6b4a696..e7fcc7eb 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/data/model/VideoStreamResponse.kt
+++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/data/model/VideoStreamResponse.kt
@@ -1,5 +1,8 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail.data.model
+package com.codandotv.streamplayerapp.feature_detail.data.model
+import kotlinx.serialization.Serializable
+
+@Serializable
data class VideoStreamResponse(
val id: String,
val name: String,
@@ -10,6 +13,7 @@ data class VideoStreamResponse(
val type: String,
)
+@Serializable
data class VideoStreamsResponse(
val id: Long,
val results: List
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/di/DetailStreamModule.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/di/DetailStreamModule.kt
similarity index 53%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/di/DetailStreamModule.kt
rename to feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/di/DetailStreamModule.kt
index 30723490..2a5e35db 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/di/DetailStreamModule.kt
+++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/di/DetailStreamModule.kt
@@ -1,18 +1,19 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail.di
+package com.codandotv.streamplayerapp.feature_detail.di
-import com.codandotv.streamplayerapp.feature_list_streams.detail.data.DetailStreamRepository
-import com.codandotv.streamplayerapp.feature_list_streams.detail.data.DetailStreamRepositoryImpl
-import com.codandotv.streamplayerapp.feature_list_streams.detail.data.DetailStreamService
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.DetailStreamUseCase
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.DetailStreamUseCaseImpl
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.VideoStreamsUseCase
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.VideoStreamsUseCaseImpl
-import com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.screens.DetailStreamViewModel
+import com.codandotv.streamplayerapp.feature_detail.data.DetailStreamRepository
+import com.codandotv.streamplayerapp.feature_detail.data.DetailStreamRepositoryImpl
+import com.codandotv.streamplayerapp.feature_detail.data.DetailStreamService
+import com.codandotv.streamplayerapp.feature_detail.data.DetailStreamServiceImpl
+import com.codandotv.streamplayerapp.feature_detail.domain.DetailStreamUseCase
+import com.codandotv.streamplayerapp.feature_detail.domain.DetailStreamUseCaseImpl
+import com.codandotv.streamplayerapp.feature_detail.domain.VideoStreamsUseCase
+import com.codandotv.streamplayerapp.feature_detail.domain.VideoStreamsUseCaseImpl
+import com.codandotv.streamplayerapp.feature_detail.presentation.screens.DetailStreamViewModel
import kotlinx.coroutines.Dispatchers
-import org.koin.androidx.viewmodel.dsl.viewModel
+import kotlinx.coroutines.IO
+import org.koin.core.module.dsl.viewModel
import org.koin.core.parameter.parametersOf
import org.koin.dsl.module
-import retrofit2.Retrofit
object DetailStreamModule {
val module = module {
@@ -49,6 +50,10 @@ object DetailStreamModule {
)
}
- factory { get().create(DetailStreamService::class.java) }
+ factory {
+ DetailStreamServiceImpl(
+ client = get()
+ )
+ }
}
}
\ No newline at end of file
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/domain/DetailStream.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/domain/DetailStream.kt
similarity index 73%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/domain/DetailStream.kt
rename to feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/domain/DetailStream.kt
index 0cd575a5..0d9f6689 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/domain/DetailStream.kt
+++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/domain/DetailStream.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail.domain
+package com.codandotv.streamplayerapp.feature_detail.domain
data class DetailStream(
val id : String,
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/domain/DetailStreamMapper.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/domain/DetailStreamMapper.kt
similarity index 69%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/domain/DetailStreamMapper.kt
rename to feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/domain/DetailStreamMapper.kt
index 174f7fc1..e12cf78f 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/domain/DetailStreamMapper.kt
+++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/domain/DetailStreamMapper.kt
@@ -1,14 +1,13 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail.domain
+package com.codandotv.streamplayerapp.feature_detail.domain
import com.codandotv.streamplayerapp.core_local_storage.domain.model.MovieEntity
-import com.codandotv.streamplayerapp.core_networking.Url.IMAGE_URL_SIZE_500
-import com.codandotv.streamplayerapp.feature_list_streams.detail.data.model.DetailStreamResponse
-import com.codandotv.streamplayerapp.feature_list_streams.detail.data.model.VideoStreamsResponse
+import com.codandotv.streamplayerapp.core_shared.Url.IMAGE_URL_SIZE_500
+import com.codandotv.streamplayerapp.feature_detail.data.model.DetailStreamResponse
+import com.codandotv.streamplayerapp.feature_detail.data.model.VideoStreamsResponse
-@Suppress("MagicNumber")
fun DetailStreamResponse.toDetailStream(isFavorite: Boolean = false): DetailStream =
DetailStream(
- id = this.id,
+ id = this.id.toString(),
title = this.title,
overview = this.overview,
tagline = this.tagline,
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/domain/DetailStreamUseCase.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/domain/DetailStreamUseCase.kt
similarity index 80%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/domain/DetailStreamUseCase.kt
rename to feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/domain/DetailStreamUseCase.kt
index 88bd4705..74c3c256 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/domain/DetailStreamUseCase.kt
+++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/domain/DetailStreamUseCase.kt
@@ -1,6 +1,6 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail.domain
+package com.codandotv.streamplayerapp.feature_detail.domain
-import com.codandotv.streamplayerapp.feature_list_streams.detail.data.DetailStreamRepository
+import com.codandotv.streamplayerapp.feature_detail.data.DetailStreamRepository
import kotlinx.coroutines.flow.Flow
interface DetailStreamUseCase {
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/domain/VideoStream.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/domain/VideoStream.kt
similarity index 50%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/domain/VideoStream.kt
rename to feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/domain/VideoStream.kt
index b97c964f..39ccb50e 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/domain/VideoStream.kt
+++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/domain/VideoStream.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail.domain
+package com.codandotv.streamplayerapp.feature_detail.domain
data class VideoStream(
val movieId: Long,
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/domain/VideoStreamsUseCase.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/domain/VideoStreamsUseCase.kt
similarity index 69%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/domain/VideoStreamsUseCase.kt
rename to feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/domain/VideoStreamsUseCase.kt
index b15bb7bd..d35544be 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/domain/VideoStreamsUseCase.kt
+++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/domain/VideoStreamsUseCase.kt
@@ -1,6 +1,6 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail.domain
+package com.codandotv.streamplayerapp.feature_detail.domain
-import com.codandotv.streamplayerapp.feature_list_streams.detail.data.DetailStreamRepository
+import com.codandotv.streamplayerapp.feature_detail.data.DetailStreamRepository
import kotlinx.coroutines.flow.Flow
interface VideoStreamsUseCase {
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/navigation/DetailStreamNavigation.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/navigation/DetailStreamNavigation.kt
similarity index 56%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/navigation/DetailStreamNavigation.kt
rename to feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/navigation/DetailStreamNavigation.kt
index 9db0b723..a52a01fb 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/navigation/DetailStreamNavigation.kt
+++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/navigation/DetailStreamNavigation.kt
@@ -1,25 +1,25 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.navigation
+package com.codandotv.streamplayerapp.feature_detail.presentation.navigation
-import androidx.lifecycle.Lifecycle
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.compose.composable
import com.codandotv.streamplayerapp.core_navigation.routes.Routes
import com.codandotv.streamplayerapp.core_navigation.routes.Routes.DETAIL_COMPLETE
import com.codandotv.streamplayerapp.core_navigation.routes.Routes.PARAM.ID
-import com.codandotv.streamplayerapp.feature_list_streams.detail.di.DetailStreamModule
-import com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.screens.DetailStreamScreen
-import org.koin.androidx.compose.koinViewModel
-import org.koin.core.context.loadKoinModules
-import org.koin.core.context.unloadKoinModules
+import com.codandotv.streamplayerapp.feature_detail.di.DetailStreamModule
+import com.codandotv.streamplayerapp.feature_detail.presentation.screens.DetailStreamScreen
+import org.koin.compose.module.rememberKoinModules
+import org.koin.compose.viewmodel.koinViewModel
+import org.koin.core.annotation.KoinExperimentalAPI
import org.koin.core.parameter.parametersOf
internal const val DEFAULT_ID = "0"
+@OptIn(KoinExperimentalAPI::class)
fun NavGraphBuilder.detailStreamNavGraph(navController: NavHostController) {
composable(DETAIL_COMPLETE) { nav ->
- if (nav.lifecycle.currentState == Lifecycle.State.STARTED) {
- loadKoinModules(DetailStreamModule.module)
+ rememberKoinModules {
+ listOf(DetailStreamModule.module)
}
DetailStreamScreen(
viewModel = koinViewModel {
@@ -29,9 +29,6 @@ fun NavGraphBuilder.detailStreamNavGraph(navController: NavHostController) {
onNavigateSearchScreen = {
navController.navigate(Routes.SEARCH)
},
- disposable = {
- unloadKoinModules(DetailStreamModule.module)
- }
)
}
}
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/screens/DetailStreamViewModel.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/screens/DetailStreamViewModel.kt
similarity index 72%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/screens/DetailStreamViewModel.kt
rename to feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/screens/DetailStreamViewModel.kt
index 5d3ca5ba..a9ae55f1 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/screens/DetailStreamViewModel.kt
+++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/screens/DetailStreamViewModel.kt
@@ -1,13 +1,14 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.screens
+package com.codandotv.streamplayerapp.feature_detail.presentation.screens
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.codandotv.streamplayerapp.core_networking.handleError.catchFailure
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.DetailStream
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.DetailStreamUseCase
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.VideoStreamsUseCase
-import com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.screens.DetailStreamsUIState.DetailStreamsLoadedUIState
-import com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.screens.DetailStreamsUIState.LoadingStreamUIState
+import com.codandotv.streamplayerapp.core_networking.resources.StringNetworking
+import com.codandotv.streamplayerapp.feature_detail.domain.DetailStream
+import com.codandotv.streamplayerapp.feature_detail.domain.DetailStreamUseCase
+import com.codandotv.streamplayerapp.feature_detail.domain.VideoStreamsUseCase
+import com.codandotv.streamplayerapp.feature_detail.presentation.screens.DetailStreamsUIState.DetailStreamsLoadedUIState
+import com.codandotv.streamplayerapp.feature_detail.presentation.screens.DetailStreamsUIState.LoadingStreamUIState
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
@@ -25,6 +26,10 @@ class DetailStreamViewModel(
private val dispatcher: CoroutineDispatcher
) : ViewModel() {
+ init {
+ loadDetail()
+ }
+
private val _uiState = MutableStateFlow(LoadingStreamUIState)
val uiState: StateFlow = _uiState.stateIn(
viewModelScope,
@@ -44,7 +49,7 @@ class DetailStreamViewModel(
.flowOn(dispatcher)
.onStart { onLoading() }
.catchFailure {
- println(">>>> ${it.errorMessage}")
+ println(">>>> ${StringNetworking.getStringResource(it.errorMessageResKey)}")
}
.collect { result ->
_uiState.update {
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/screens/DetailStreamsScreen.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/screens/DetailStreamsScreen.kt
similarity index 75%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/screens/DetailStreamsScreen.kt
rename to feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/screens/DetailStreamsScreen.kt
index d4cbc47a..df3f2bfa 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/screens/DetailStreamsScreen.kt
+++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/screens/DetailStreamsScreen.kt
@@ -1,7 +1,5 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.screens
+package com.codandotv.streamplayerapp.feature_detail.presentation.screens
-import android.annotation.SuppressLint
-import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
@@ -12,62 +10,46 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.filled.FileDownload
+import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.PlayArrow
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CircularProgressIndicator
-import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.platform.LocalLifecycleOwner
-import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.compose.LifecycleEventEffect
-import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
-import com.codandotv.streamplayerapp.core_shared_ui.widget.SharingStreamCustomView
-import com.codandotv.streamplayerapp.feature.list.streams.R
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.DetailStream
-import com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.widget.DetailStreamActionOption
-import com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.widget.DetailStreamButtonAction
-import com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.widget.DetailStreamImagePreview
-import com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.widget.DetailStreamRowHeader
-import com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.widget.DetailStreamToolbar
-import org.koin.androidx.compose.koinViewModel
+import com.codandotv.streamplayerapp.core_shared_ui.widget.SharingStreamPlatform
+import com.codandotv.streamplayerapp.feature_detail.domain.DetailStream
+import com.codandotv.streamplayerapp.feature_detail.presentation.widget.DetailStreamActionOption
+import com.codandotv.streamplayerapp.feature_detail.presentation.widget.DetailStreamButtonAction
+import com.codandotv.streamplayerapp.feature_detail.presentation.widget.DetailStreamImagePreview
+import com.codandotv.streamplayerapp.feature_detail.presentation.widget.DetailStreamRowHeader
+import com.codandotv.streamplayerapp.feature_detail.presentation.widget.DetailStreamToolbar
+import org.jetbrains.compose.resources.stringResource
+import org.koin.compose.viewmodel.koinViewModel
+import streamplayerapp_kmp.feature_detail.generated.resources.Res
+import streamplayerapp_kmp.feature_detail.generated.resources.detail_default_text_secondary_button
+import streamplayerapp_kmp.feature_detail.generated.resources.detail_watch_primary_button
@Composable
fun DetailStreamScreen(
viewModel: DetailStreamViewModel = koinViewModel(),
navController: NavController,
- disposable: () -> Unit = {},
onNavigateSearchScreen: () -> Unit = {},
) {
- val uiState by viewModel.uiState.collectAsStateWithLifecycle()
-
- val lifecycleOwner = LocalLifecycleOwner.current
-
- LifecycleEventEffect(Lifecycle.Event.ON_START) {
- viewModel.loadDetail()
- }
-
- DisposableEffect(lifecycleOwner) {
- onDispose {
- disposable.invoke()
- }
- }
+ val uiState by viewModel.uiState.collectAsState()
when (uiState) {
is DetailStreamsUIState.DetailStreamsLoadedUIState -> {
@@ -92,9 +74,7 @@ fun DetailStreamScreen(
}
}
-@OptIn(ExperimentalMaterial3Api::class)
@Suppress("LongMethod")
-@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@Composable
private fun SetupDetailScreen(
onToggleToMyList: (DetailStream) -> Unit,
@@ -154,7 +134,7 @@ private fun SetupDetailScreen(
),
imageVector = Icons.Filled.PlayArrow,
imageVectorColor = MaterialTheme.colorScheme.onSurface,
- text = stringResource(R.string.detail_watch_primary_button),
+ text = stringResource(Res.string.detail_watch_primary_button),
textColor = MaterialTheme.colorScheme.onSurface
)
Spacer(modifier = Modifier.height(4.dp))
@@ -162,9 +142,9 @@ private fun SetupDetailScreen(
buttonsColors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.onSurfaceVariant
),
- imageVector = Icons.Filled.FileDownload,
+ imageVector = Icons.Filled.Add,
imageVectorColor = MaterialTheme.colorScheme.onSurface,
- text = stringResource(id = R.string.detail_default_text_secondary_button),
+ text = stringResource(Res.string.detail_default_text_secondary_button),
textColor = MaterialTheme.colorScheme.onSurface,
)
Text(
@@ -185,19 +165,19 @@ private fun SetupDetailScreen(
}
}
if (showDialog.value) {
- SharingStreamCustomView(
+ SharingStreamPlatform(
contentTitle = uiState.detailStream.title,
contentUrl = uiState.detailStream.url,
setShowDialog = {
showDialog.value = it
})
}
- BackHandler {
+ /*BackHandler {
if (showDialog.value) {
showDialog.value = false
} else {
navController.navigateUp()
}
- }
+ }*/
})
}
\ No newline at end of file
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/screens/DetailStreamsUIState.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/screens/DetailStreamsUIState.kt
similarity index 58%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/screens/DetailStreamsUIState.kt
rename to feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/screens/DetailStreamsUIState.kt
index cfc4ebb7..66c2a144 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/screens/DetailStreamsUIState.kt
+++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/screens/DetailStreamsUIState.kt
@@ -1,6 +1,6 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.screens
+package com.codandotv.streamplayerapp.feature_detail.presentation.screens
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.DetailStream
+import com.codandotv.streamplayerapp.feature_detail.domain.DetailStream
sealed class DetailStreamsUIState {
data class DetailStreamsLoadedUIState(
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/widget/DetailStreamActionOption.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/widget/DetailStreamActionOption.kt
similarity index 72%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/widget/DetailStreamActionOption.kt
rename to feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/widget/DetailStreamActionOption.kt
index e4b92603..03b52f98 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/widget/DetailStreamActionOption.kt
+++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/widget/DetailStreamActionOption.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.widget
+package com.codandotv.streamplayerapp.feature_detail.presentation.widget
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
@@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Check
-import androidx.compose.material.icons.filled.Download
import androidx.compose.material.icons.filled.Share
import androidx.compose.material.icons.filled.ThumbUp
import androidx.compose.runtime.Composable
@@ -18,10 +17,14 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.res.stringResource
import com.codandotv.streamplayerapp.core_shared_ui.widget.IconWithText
-import com.codandotv.streamplayerapp.feature.list.streams.R
-import com.codandotv.streamplayerapp.feature_list_streams.detail.domain.DetailStream
+import com.codandotv.streamplayerapp.feature_detail.domain.DetailStream
+import org.jetbrains.compose.resources.stringResource
+import streamplayerapp_kmp.feature_detail.generated.resources.Res
+import streamplayerapp_kmp.feature_detail.generated.resources.detail_classification
+import streamplayerapp_kmp.feature_detail.generated.resources.detail_download
+import streamplayerapp_kmp.feature_detail.generated.resources.detail_my_list
+import streamplayerapp_kmp.feature_detail.generated.resources.detail_share
@Composable
fun DetailStreamActionOption(
@@ -49,28 +52,28 @@ fun DetailStreamActionOption(
},
imageVector = iconCheckList,
imageColor = Color.White,
- text = stringResource(id = R.string.detail_my_list),
+ text = stringResource(Res.string.detail_my_list),
textColor = Color.Gray,
)
IconWithText(
onClick = { TODO("Implementar mecanismo de classificação.") },
imageVector = Icons.Filled.ThumbUp,
imageColor = Color.White,
- text = stringResource(id = R.string.detail_classification),
+ text = stringResource(Res.string.detail_classification),
textColor = Color.Gray,
)
IconWithText(
onClick = { onShowSharingOptions.invoke() },
imageVector = Icons.Filled.Share,
imageColor = Color.White,
- text = stringResource(id = R.string.detail_share),
+ text = stringResource(Res.string.detail_share),
textColor = Color.Gray,
)
IconWithText(
onClick = { TODO("Implementar mecanismo de download.") },
- imageVector = Icons.Filled.Download,
+ imageVector = Icons.Filled.Share,
imageColor = Color.White,
- text = stringResource(id = R.string.detail_download),
+ text = stringResource(Res.string.detail_download),
textColor = Color.Gray,
)
}
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/widget/DetailStreamButtonAction.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/widget/DetailStreamButtonAction.kt
similarity index 95%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/widget/DetailStreamButtonAction.kt
rename to feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/widget/DetailStreamButtonAction.kt
index 0cdefd53..c97b9f1e 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/widget/DetailStreamButtonAction.kt
+++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/widget/DetailStreamButtonAction.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.widget
+package com.codandotv.streamplayerapp.feature_detail.presentation.widget
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/widget/DetailStreamImagePreview.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/widget/DetailStreamImagePreview.kt
similarity index 75%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/widget/DetailStreamImagePreview.kt
rename to feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/widget/DetailStreamImagePreview.kt
index e1451f60..5d17576d 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/widget/DetailStreamImagePreview.kt
+++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/widget/DetailStreamImagePreview.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.widget
+package com.codandotv.streamplayerapp.feature_detail.presentation.widget
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
@@ -14,12 +14,13 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
-import coil.compose.AsyncImage
-import com.codandotv.streamplayerapp.core_shared_ui.widget.PlayerComponent
-import com.codandotv.streamplayerapp.feature.list.streams.R
-import com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.screens.DetailStreamsUIState.DetailStreamsLoadedUIState
+import com.codandotv.streamplayerapp.core_shared_ui.widget.PlayerComponentPlatform
+import com.codandotv.streamplayerapp.core_shared_ui.widget.WebImage
+import com.codandotv.streamplayerapp.feature_detail.presentation.screens.DetailStreamsUIState.DetailStreamsLoadedUIState
+import org.jetbrains.compose.resources.painterResource
+import streamplayerapp_kmp.feature_detail.generated.resources.Res
+import streamplayerapp_kmp.feature_detail.generated.resources.play_circle
@Suppress("MagicNumber")
@Composable
@@ -36,12 +37,12 @@ fun DetailStreamImagePreview(
contentAlignment = Alignment.Center
) {
if (showPlayer) {
- PlayerComponent(
+ PlayerComponentPlatform(
videoId = uiState.videoId ?: ""
)
} else {
- AsyncImage(
- model = uiState.detailStream.url,
+ WebImage(
+ imageUrl = uiState.detailStream.url,
contentScale = ContentScale.FillBounds,
contentDescription = uiState.detailStream.tagline,
modifier = Modifier
@@ -56,7 +57,7 @@ fun DetailStreamImagePreview(
.align(Alignment.Center),
)
Icon(
- painter = painterResource(id = R.drawable.play_circle),
+ painter = painterResource(Res.drawable.play_circle),
tint = Color.White,
contentDescription = null,
modifier = Modifier
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/widget/DetailStreamRowHeader.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/widget/DetailStreamRowHeader.kt
similarity index 71%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/widget/DetailStreamRowHeader.kt
rename to feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/widget/DetailStreamRowHeader.kt
index 5ef2dfa5..cf5d5c0f 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/widget/DetailStreamRowHeader.kt
+++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/widget/DetailStreamRowHeader.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.widget
+package com.codandotv.streamplayerapp.feature_detail.presentation.widget
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Row
@@ -11,13 +11,15 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp
-import com.codandotv.streamplayerapp.feature.list.streams.R
+import org.jetbrains.compose.resources.painterResource
+import org.jetbrains.compose.resources.stringResource
+import streamplayerapp_kmp.feature_detail.generated.resources.Res
+import streamplayerapp_kmp.feature_detail.generated.resources.detail_movie
+import streamplayerapp_kmp.feature_detail.generated.resources.netflix_detail
@Composable
fun DetailStreamRowHeader(
@@ -28,7 +30,7 @@ fun DetailStreamRowHeader(
modifier = modifier
) {
Image(
- painter = painterResource(id = R.drawable.netflix_detail),
+ painter = painterResource(Res.drawable.netflix_detail),
contentDescription = null,
modifier = Modifier
.size(26.dp)
@@ -36,7 +38,7 @@ fun DetailStreamRowHeader(
)
Text(
- text = stringResource(id = R.string.detail_movie),
+ text = stringResource(Res.string.detail_movie),
modifier = Modifier.offset(x = (-6).dp),
style = MaterialTheme.typography.headlineMedium.copy(
color = Color.Gray,
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/widget/DetailStreamToolbar.kt b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/widget/DetailStreamToolbar.kt
similarity index 66%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/widget/DetailStreamToolbar.kt
rename to feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/widget/DetailStreamToolbar.kt
index 152ebe46..cdf05dce 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/presentation/widget/DetailStreamToolbar.kt
+++ b/feature-detail/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_detail/presentation/widget/DetailStreamToolbar.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail.presentation.widget
+package com.codandotv.streamplayerapp.feature_detail.presentation.widget
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.height
@@ -13,11 +13,15 @@ import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
-import com.codandotv.streamplayerapp.feature.list.streams.R
+import org.jetbrains.compose.resources.painterResource
+import org.jetbrains.compose.resources.stringResource
+import streamplayerapp_kmp.core_shared_ui.generated.resources.perfil_fake
+import streamplayerapp_kmp.feature_detail.generated.resources.Res
+import streamplayerapp_kmp.core_shared_ui.generated.resources.Res as SharedRes
+import streamplayerapp_kmp.feature_detail.generated.resources.detail_back
+import streamplayerapp_kmp.feature_detail.generated.resources.detail_search
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -32,7 +36,7 @@ fun DetailStreamToolbar(
IconButton(onClick = { navController.navigateUp() }) {
Icon(
imageVector = Icons.Filled.ArrowBack,
- contentDescription = stringResource(id = R.string.detail_back)
+ contentDescription = stringResource(Res.string.detail_back)
)
}
}, actions = {
@@ -42,12 +46,12 @@ fun DetailStreamToolbar(
Icon(
imageVector = Icons.Default.Search,
tint = Color.White,
- contentDescription = stringResource(id = R.string.detail_search)
+ contentDescription = stringResource(Res.string.detail_search)
)
}
IconButton(onClick = { }) {
Image(
- painter = painterResource(id = com.codandotv.streamplayerapp.core.shared.ui.R.drawable.perfil_fake),
+ painter = painterResource(SharedRes.drawable.perfil_fake),
contentDescription = null
)
}
diff --git a/feature-favorites/build.gradle.kts b/feature-favorites/build.gradle.kts
deleted file mode 100644
index 6bf94b61..00000000
--- a/feature-favorites/build.gradle.kts
+++ /dev/null
@@ -1,19 +0,0 @@
-@file:Suppress("UnstableApiUsage")
-plugins {
- id("com.streamplayer.android-library")
- id("com.streamplayer.compose")
-}
-
-dependencies {
- implementation(projects.coreNetworking)
- implementation(projects.coreNavigation)
- implementation(projects.coreShared)
- implementation(projects.coreSharedUi)
-
- implementation(libs.bundles.koin)
- implementation(libs.bundles.networking)
- implementation(libs.bundles.androidSupport)
- implementation(libs.coil)
-
- testImplementation(libs.bundles.test)
-}
\ No newline at end of file
diff --git a/feature-list-streams/.gitignore b/feature-list-streams/.gitignore
index 42afabfd..581f8daa 100644
--- a/feature-list-streams/.gitignore
+++ b/feature-list-streams/.gitignore
@@ -1 +1 @@
-/build
\ No newline at end of file
+**/build/**
\ No newline at end of file
diff --git a/feature-list-streams/build.gradle.kts b/feature-list-streams/build.gradle.kts
index 7faf9beb..53b2eb8c 100644
--- a/feature-list-streams/build.gradle.kts
+++ b/feature-list-streams/build.gradle.kts
@@ -1,30 +1,37 @@
@file:Suppress("UnstableApiUsage")
plugins {
- id("com.streamplayer.android-library")
- id("com.streamplayer.compose")
- alias(libs.plugins.ksp)
+ id("com.streamplayer.kmp-library")
+ alias(libs.plugins.jetbrains.compose)
+ alias(libs.plugins.compose.compiler)
}
-dependencies {
- implementation(projects.coreNetworking)
- implementation(projects.coreNavigation)
- implementation(projects.coreShared)
- implementation(projects.coreSharedUi)
- implementation(projects.coreLocalStorage)
+kotlin {
+ sourceSets {
+ androidMain.dependencies {
+ implementation(compose.preview)
+ }
- implementation(libs.bundles.koin)
- implementation(libs.koin.annotations)
- ksp(libs.koin.compiler)
+ commonMain.dependencies {
+ implementation(projects.coreNetworking)
+ implementation(projects.coreNavigation)
+ implementation(projects.coreShared)
+ implementation(projects.coreSharedUi)
+ implementation(projects.coreLocalStorage)
- implementation(libs.bundles.networking)
- implementation(libs.roomRuntime)
- implementation(libs.bundles.androidSupport)
- implementation(libs.coil)
+ implementation(compose.components.resources)
+ implementation(compose.material3)
+ implementation(compose.ui)
- testImplementation(libs.bundles.test)
-}
+ implementation(libs.paging.compose)
+
+ implementation(libs.navigation.compose)
+
+ implementation(libs.ktor.client.content.serialization.json)
+ implementation(libs.ktor.client.content.negotiation)
-ksp {
- arg("KOIN_CONFIG_CHECK","true")
+ implementation(libs.koin.compose)
+ implementation(libs.koin.compose.viewmodel)
+ }
+ }
}
\ No newline at end of file
diff --git a/feature-list-streams/consumer-rules.pro b/feature-list-streams/consumer-rules.pro
deleted file mode 100644
index e69de29b..00000000
diff --git a/feature-list-streams/proguard-rules.pro b/feature-list-streams/proguard-rules.pro
deleted file mode 100644
index 481bb434..00000000
--- a/feature-list-streams/proguard-rules.pro
+++ /dev/null
@@ -1,21 +0,0 @@
-# Add project specific ProGuard rules here.
-# You can control the set of applied configuration files using the
-# proguardFiles setting in build.gradle.
-#
-# For more details, see
-# http://developer.android.com/guide/developing/tools/proguard.html
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/feature-list-streams/src/androidMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screen/ListStreamsScreenPreview.kt b/feature-list-streams/src/androidMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screen/ListStreamsScreenPreview.kt
new file mode 100644
index 00000000..0717265b
--- /dev/null
+++ b/feature-list-streams/src/androidMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screen/ListStreamsScreenPreview.kt
@@ -0,0 +1,12 @@
+package com.codandotv.streamplayerapp.feature_list_streams.list.presentation.screen
+
+import androidx.compose.runtime.Composable
+import androidx.navigation.compose.rememberNavController
+import com.codandotv.streamplayerapp.core_shared_ui.theme.ThemePreviews
+import com.codandotv.streamplayerapp.feature_list_streams.list.presentation.screens.ListStreamsScreen
+
+@ThemePreviews
+@Composable
+fun ListStreamsScreenPreview() {
+ ListStreamsScreen(navController = rememberNavController(), profilePicture = "")
+}
diff --git a/feature-list-streams/src/androidMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/widgets/HighlightBannerPreview.kt b/feature-list-streams/src/androidMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/widgets/HighlightBannerPreview.kt
new file mode 100644
index 00000000..b5e899a9
--- /dev/null
+++ b/feature-list-streams/src/androidMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/widgets/HighlightBannerPreview.kt
@@ -0,0 +1,50 @@
+package com.codandotv.streamplayerapp.feature_list_streams.list.presentation.widgets
+
+import androidx.compose.runtime.Composable
+import com.codandotv.streamplayerapp.core_shared_ui.theme.ThemePreviews
+import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.IconAndTextInfo
+import org.jetbrains.compose.resources.stringResource
+import streamplayerapp_kmp.core_shared_ui.generated.resources.Res
+import streamplayerapp_kmp.core_shared_ui.generated.resources.app_name
+import streamplayerapp_kmp.core_shared_ui.generated.resources.ic_add
+import streamplayerapp_kmp.core_shared_ui.generated.resources.ic_info
+import streamplayerapp_kmp.core_shared_ui.generated.resources.ic_play
+import streamplayerapp_kmp.feature_list_streams.generated.resources.ic_top_10
+import streamplayerapp_kmp.feature_list_streams.generated.resources.list_highlight_banner_add
+import streamplayerapp_kmp.feature_list_streams.generated.resources.list_highlight_banner_info
+import streamplayerapp_kmp.feature_list_streams.generated.resources.list_highlight_banner_watch
+
+@ThemePreviews
+@Composable
+fun HighlightBannerPreview() {
+ HighlightBanner(
+ data = com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.HighlightBanner(
+ name = stringResource(Res.string.app_name),
+ imageUrl = String(),
+ contentType = com.codandotv.streamplayerapp.feature_list_streams.core.ContentType.getContentName(
+ com.codandotv.streamplayerapp.feature_list_streams.core.ContentType.SHOW
+ ),
+ contentTypeAsPlural = com.codandotv.streamplayerapp.feature_list_streams.core.ContentType.getContentNameAsPlural(
+ com.codandotv.streamplayerapp.feature_list_streams.core.ContentType.SHOW
+ ),
+ extraInfo = IconAndTextInfo(
+ streamplayerapp_kmp.feature_list_streams.generated.resources.Res.drawable.ic_top_10,
+ com.codandotv.streamplayerapp.feature_list_streams.core.ContentType.getContentName(
+ com.codandotv.streamplayerapp.feature_list_streams.core.ContentType.SHOW
+ )
+ ),
+ leftButton = IconAndTextInfo(
+ Res.drawable.ic_add,
+ streamplayerapp_kmp.feature_list_streams.generated.resources.Res.string.list_highlight_banner_add
+ ),
+ centralButton = IconAndTextInfo(
+ Res.drawable.ic_play,
+ streamplayerapp_kmp.feature_list_streams.generated.resources.Res.string.list_highlight_banner_watch
+ ),
+ rightButton = IconAndTextInfo(
+ Res.drawable.ic_info,
+ streamplayerapp_kmp.feature_list_streams.generated.resources.Res.string.list_highlight_banner_info
+ ),
+ )
+ )
+}
diff --git a/feature-list-streams/src/commonMain/composeResources/drawable/ic_top_10.png b/feature-list-streams/src/commonMain/composeResources/drawable/ic_top_10.png
new file mode 100644
index 00000000..03b1f3b0
Binary files /dev/null and b/feature-list-streams/src/commonMain/composeResources/drawable/ic_top_10.png differ
diff --git a/feature-list-streams/src/main/res/drawable/image_placeholder.xml b/feature-list-streams/src/commonMain/composeResources/drawable/image_placeholder.xml
similarity index 100%
rename from feature-list-streams/src/main/res/drawable/image_placeholder.xml
rename to feature-list-streams/src/commonMain/composeResources/drawable/image_placeholder.xml
diff --git a/feature-list-streams/src/main/res/drawable/netflix_horizontal_logo.xml b/feature-list-streams/src/commonMain/composeResources/drawable/netflix_horizontal_logo.xml
similarity index 100%
rename from feature-list-streams/src/main/res/drawable/netflix_horizontal_logo.xml
rename to feature-list-streams/src/commonMain/composeResources/drawable/netflix_horizontal_logo.xml
diff --git a/feature-list-streams/src/commonMain/composeResources/values/strings.xml b/feature-list-streams/src/commonMain/composeResources/values/strings.xml
new file mode 100644
index 00000000..2211d1eb
--- /dev/null
+++ b/feature-list-streams/src/commonMain/composeResources/values/strings.xml
@@ -0,0 +1,20 @@
+
+
+
+ Série
+ Séries
+ Filme
+ Filmes
+
+ Minha lista
+ Saiba mais
+ Assistir
+ Top 1 em %s hoje
+
+ Ícone Reprodução
+ Ícone adicionar
+ Ícone informações
+ Poster de conteúdo em destaque
+ Ícone top 10
+
+
\ No newline at end of file
diff --git a/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/core/ContentType.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/core/ContentType.kt
new file mode 100644
index 00000000..38c98665
--- /dev/null
+++ b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/core/ContentType.kt
@@ -0,0 +1,21 @@
+package com.codandotv.streamplayerapp.feature_list_streams.core
+
+import org.jetbrains.compose.resources.StringResource
+import streamplayerapp_kmp.feature_list_streams.generated.resources.Res
+import streamplayerapp_kmp.feature_list_streams.generated.resources.list_content_type_film
+import streamplayerapp_kmp.feature_list_streams.generated.resources.list_content_type_film_plural
+import streamplayerapp_kmp.feature_list_streams.generated.resources.list_content_type_show
+import streamplayerapp_kmp.feature_list_streams.generated.resources.list_content_type_show_plural
+
+enum class ContentType(val contentName: StringResource, val contentNameAsPlural: StringResource) {
+ SHOW(Res.string.list_content_type_show, Res.string.list_content_type_show_plural),
+ FILM(Res.string.list_content_type_film, Res.string.list_content_type_film_plural);
+
+ companion object {
+ fun getContentName(contentType: ContentType) =
+ entries.first { contentType == it }.contentName
+
+ fun getContentNameAsPlural(contentType: ContentType) =
+ entries.first { contentType == it }.contentNameAsPlural
+ }
+}
\ No newline at end of file
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/data/ListStreamRepository.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/data/ListStreamRepository.kt
similarity index 97%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/data/ListStreamRepository.kt
rename to feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/data/ListStreamRepository.kt
index 42a14d44..dce60971 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/data/ListStreamRepository.kt
+++ b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/data/ListStreamRepository.kt
@@ -10,7 +10,6 @@ import com.codandotv.streamplayerapp.feature_list_streams.list.domain.toGenres
import com.codandotv.streamplayerapp.feature_list_streams.list.domain.toStream
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
-import org.koin.core.annotation.Factory
interface ListStreamRepository {
suspend fun getGenres(): Flow>
@@ -20,7 +19,6 @@ interface ListStreamRepository {
fun loadMovies(genre: Genre): Flow>
}
-@Factory
class ListStreamRepositoryImpl(
private val service: ListStreamService,
) : ListStreamRepository {
diff --git a/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/data/ListStreamService.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/data/ListStreamService.kt
new file mode 100644
index 00000000..e2634895
--- /dev/null
+++ b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/data/ListStreamService.kt
@@ -0,0 +1,59 @@
+package com.codandotv.streamplayerapp.feature_list_streams.list.data
+
+import ListStreamResponse
+import com.codandotv.streamplayerapp.core_networking.handleError.NetworkResponse
+import com.codandotv.streamplayerapp.core_networking.handleError.safeRequest
+import com.codandotv.streamplayerapp.feature_list_streams.list.data.model.GenresResponse
+import io.ktor.client.HttpClient
+import io.ktor.client.request.parameter
+import io.ktor.client.request.url
+
+interface ListStreamService {
+ suspend fun getMovies(genres: String): NetworkResponse
+ suspend fun getPaginatedMovies(genres: String, page: Int): NetworkResponse
+ suspend fun getGenres(): NetworkResponse
+ suspend fun getTopRatedMovies(
+ sortBy: String = "vote_average.desc",
+ page: Int = 1
+ ): NetworkResponse
+}
+
+class ListStreamServiceImpl(
+ private val client: HttpClient
+) : ListStreamService {
+
+ override suspend fun getMovies(genres: String): NetworkResponse {
+ return client.safeRequest {
+ url("discover/movie")
+ parameter("with_genres", genres)
+ }
+ }
+
+ override suspend fun getPaginatedMovies(
+ genres: String,
+ page: Int
+ ): NetworkResponse {
+ return client.safeRequest {
+ url("discover/movie")
+ parameter("with_genres", genres)
+ parameter("page", page)
+ }
+ }
+
+ override suspend fun getGenres(): NetworkResponse {
+ return client.safeRequest {
+ url("genre/movie/list")
+ }
+ }
+
+ override suspend fun getTopRatedMovies(
+ sortBy: String,
+ page: Int
+ ): NetworkResponse {
+ return client.safeRequest {
+ url("discover/movie")
+ parameter("sort_by", sortBy)
+ parameter("page", page)
+ }
+ }
+}
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/data/StreamDataSource.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/data/StreamDataSource.kt
similarity index 100%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/data/StreamDataSource.kt
rename to feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/data/StreamDataSource.kt
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/data/model/GenresResponse.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/data/model/GenresResponse.kt
similarity index 74%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/data/model/GenresResponse.kt
rename to feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/data/model/GenresResponse.kt
index 90f9bed1..3533dcdd 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/data/model/GenresResponse.kt
+++ b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/data/model/GenresResponse.kt
@@ -1,10 +1,14 @@
package com.codandotv.streamplayerapp.feature_list_streams.list.data.model
+import kotlinx.serialization.Serializable
+
+@Serializable
data class GenreResponse(
val id: Long,
val name: String
)
+@Serializable
data class GenresResponse(
val genres: List
)
\ No newline at end of file
diff --git a/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/data/model/ListStreamResponse.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/data/model/ListStreamResponse.kt
new file mode 100644
index 00000000..89574e2c
--- /dev/null
+++ b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/data/model/ListStreamResponse.kt
@@ -0,0 +1,14 @@
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class StreamResponse(
+ val id: Int,
+ val title: String,
+ val overview: String,
+ val poster_path: String? = null
+)
+
+@Serializable
+data class ListStreamResponse(
+ val results: List
+)
diff --git a/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/di/ListStreamModule.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/di/ListStreamModule.kt
new file mode 100644
index 00000000..ffbfb75e
--- /dev/null
+++ b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/di/ListStreamModule.kt
@@ -0,0 +1,63 @@
+package com.codandotv.streamplayerapp.feature_list_streams.list.di
+
+import com.codandotv.streamplayerapp.feature_list_streams.list.data.ListStreamRepository
+import com.codandotv.streamplayerapp.feature_list_streams.list.data.ListStreamRepositoryImpl
+import com.codandotv.streamplayerapp.feature_list_streams.list.data.ListStreamService
+import com.codandotv.streamplayerapp.feature_list_streams.list.data.ListStreamServiceImpl
+import com.codandotv.streamplayerapp.feature_list_streams.list.domain.GetGenresUseCase
+import com.codandotv.streamplayerapp.feature_list_streams.list.domain.GetGenresUseCaseImpl
+import com.codandotv.streamplayerapp.feature_list_streams.list.domain.GetTopRatedStream
+import com.codandotv.streamplayerapp.feature_list_streams.list.domain.GetTopRatedStreamImpl
+import com.codandotv.streamplayerapp.feature_list_streams.list.domain.ListStreamAnalytics
+import com.codandotv.streamplayerapp.feature_list_streams.list.domain.ListStreamAnalyticsImpl
+import com.codandotv.streamplayerapp.feature_list_streams.list.domain.ListStreamUseCase
+import com.codandotv.streamplayerapp.feature_list_streams.list.domain.ListStreamUseCaseImpl
+import com.codandotv.streamplayerapp.feature_list_streams.list.presentation.screens.ListStreamViewModel
+import org.koin.core.module.dsl.viewModel
+import org.koin.dsl.module
+
+object ListStreamModule {
+ val module = module {
+ viewModel {
+ ListStreamViewModel(
+ listStreams = get(),
+ listGenres = get(),
+ latestStream = get()
+ )
+ }
+
+ factory {
+ ListStreamUseCaseImpl(
+ repository = get()
+ )
+ }
+
+ factory {
+ GetGenresUseCaseImpl(
+ repository = get()
+ )
+ }
+
+ factory {
+ GetTopRatedStreamImpl(
+ repository = get()
+ )
+ }
+
+ factory {
+ ListStreamAnalyticsImpl()
+ }
+
+ factory {
+ ListStreamRepositoryImpl(
+ service = get(),
+ )
+ }
+
+ factory {
+ ListStreamServiceImpl(
+ client = get()
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/GetGenresUseCase.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/GetGenresUseCase.kt
similarity index 92%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/GetGenresUseCase.kt
rename to feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/GetGenresUseCase.kt
index 36b2b4d9..e3da0b8c 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/GetGenresUseCase.kt
+++ b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/GetGenresUseCase.kt
@@ -3,13 +3,11 @@ package com.codandotv.streamplayerapp.feature_list_streams.list.domain
import com.codandotv.streamplayerapp.feature_list_streams.list.data.ListStreamRepository
import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.Genre
import kotlinx.coroutines.flow.Flow
-import org.koin.core.annotation.Factory
interface GetGenresUseCase {
suspend operator fun invoke(): Flow>
}
-@Factory
class GetGenresUseCaseImpl(
private val repository: ListStreamRepository
) : GetGenresUseCase {
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/GetLatestMovieUseCase.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/GetLatestMovieUseCase.kt
similarity index 92%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/GetLatestMovieUseCase.kt
rename to feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/GetLatestMovieUseCase.kt
index 7257a40c..a5300816 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/GetLatestMovieUseCase.kt
+++ b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/GetLatestMovieUseCase.kt
@@ -3,13 +3,11 @@ package com.codandotv.streamplayerapp.feature_list_streams.list.domain
import com.codandotv.streamplayerapp.feature_list_streams.list.data.ListStreamRepository
import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.Stream
import kotlinx.coroutines.flow.Flow
-import org.koin.core.annotation.Factory
interface GetTopRatedStream {
suspend operator fun invoke(): Flow
}
-@Factory
class GetTopRatedStreamImpl(
private val repository: ListStreamRepository
) : GetTopRatedStream {
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/ListMovieUseCase.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/ListMovieUseCase.kt
similarity index 93%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/ListMovieUseCase.kt
rename to feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/ListMovieUseCase.kt
index 367f47be..b4aff62b 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/ListMovieUseCase.kt
+++ b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/ListMovieUseCase.kt
@@ -5,13 +5,11 @@ import com.codandotv.streamplayerapp.feature_list_streams.list.data.ListStreamRe
import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.Genre
import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.Stream
import kotlinx.coroutines.flow.Flow
-import org.koin.core.annotation.Factory
interface ListStreamUseCase {
operator fun invoke(genre: Genre): Flow>
}
-@Factory
class ListStreamUseCaseImpl(
private val repository: ListStreamRepository
) : ListStreamUseCase {
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/ListStreamAnalytics.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/ListStreamAnalytics.kt
similarity index 75%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/ListStreamAnalytics.kt
rename to feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/ListStreamAnalytics.kt
index e599c1fa..e2fc2866 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/ListStreamAnalytics.kt
+++ b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/ListStreamAnalytics.kt
@@ -1,8 +1,6 @@
package com.codandotv.streamplayerapp.feature_list_streams.list.domain
-import org.koin.core.annotation.Factory
interface ListStreamAnalytics
-@Factory
class ListStreamAnalyticsImpl : ListStreamAnalytics
\ No newline at end of file
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/ListStreamMapper.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/ListStreamMapper.kt
similarity index 78%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/ListStreamMapper.kt
rename to feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/ListStreamMapper.kt
index 5e5d86c0..105d61a4 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/ListStreamMapper.kt
+++ b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/ListStreamMapper.kt
@@ -1,9 +1,9 @@
package com.codandotv.streamplayerapp.feature_list_streams.list.domain
-import com.codandotv.streamplayerapp.core_networking.Url
+import ListStreamResponse
+import StreamResponse
+import com.codandotv.streamplayerapp.core_shared.Url
import com.codandotv.streamplayerapp.feature_list_streams.list.data.model.GenresResponse
-import com.codandotv.streamplayerapp.feature_list_streams.list.data.model.ListStreamResponse
-import com.codandotv.streamplayerapp.feature_list_streams.list.data.model.StreamResponse
import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.Genre
import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.ListStream
import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.Stream
@@ -24,5 +24,5 @@ fun StreamResponse.toStream(): Stream = Stream(
description = overview,
name = title,
posterPathUrl = "${Url.IMAGE_URL_SIZE_300}${poster_path}",
- id = id
+ id = id.toString()
)
\ No newline at end of file
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/model/Genre.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/model/Genre.kt
similarity index 100%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/model/Genre.kt
rename to feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/model/Genre.kt
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/model/HighlightBanner.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/model/HighlightBanner.kt
similarity index 51%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/model/HighlightBanner.kt
rename to feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/model/HighlightBanner.kt
index 7bdd369d..75c93595 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/model/HighlightBanner.kt
+++ b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/model/HighlightBanner.kt
@@ -1,24 +1,20 @@
package com.codandotv.streamplayerapp.feature_list_streams.list.domain.model
-import android.os.Parcelable
-import androidx.annotation.DrawableRes
-import androidx.annotation.StringRes
-import kotlinx.parcelize.Parcelize
+import org.jetbrains.compose.resources.DrawableResource
+import org.jetbrains.compose.resources.StringResource
-@Parcelize
data class HighlightBanner(
val name: String,
val imageUrl: String,
- val contentType: Int,
- val contentTypeAsPlural: Int,
+ val contentType: StringResource,
+ val contentTypeAsPlural: StringResource,
val extraInfo: IconAndTextInfo,
val leftButton: IconAndTextInfo,
val centralButton: IconAndTextInfo,
val rightButton: IconAndTextInfo
-) : Parcelable
+)
-@Parcelize
data class IconAndTextInfo(
- @DrawableRes val icon: Int,
- @StringRes val text: Int
-) : Parcelable
\ No newline at end of file
+ val icon: DrawableResource,
+ val text: StringResource
+)
\ No newline at end of file
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/model/ListStream.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/model/ListStream.kt
similarity index 100%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/domain/model/ListStream.kt
rename to feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/domain/model/ListStream.kt
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/navigation/ListStreamsNavigation.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/navigation/ListStreamsNavigation.kt
similarity index 72%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/navigation/ListStreamsNavigation.kt
rename to feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/navigation/ListStreamsNavigation.kt
index ac58e2be..1ed73ef9 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/navigation/ListStreamsNavigation.kt
+++ b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/navigation/ListStreamsNavigation.kt
@@ -1,7 +1,5 @@
package com.codandotv.streamplayerapp.feature_list_streams.list.presentation.navigation
-import androidx.activity.compose.BackHandler
-import androidx.lifecycle.Lifecycle
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.compose.composable
@@ -12,19 +10,22 @@ import com.codandotv.streamplayerapp.core_navigation.routes.Routes.DETAIL
import com.codandotv.streamplayerapp.core_navigation.routes.Routes.PROFILE_PICKER
import com.codandotv.streamplayerapp.feature_list_streams.list.di.ListStreamModule
import com.codandotv.streamplayerapp.feature_list_streams.list.presentation.screens.ListStreamsScreen
-import org.koin.core.context.loadKoinModules
-import org.koin.core.context.unloadKoinModules
-import org.koin.ksp.generated.module
+import org.koin.compose.module.rememberKoinModules
+import org.koin.core.annotation.KoinExperimentalAPI
internal const val DEFAULT_ID = ""
+@OptIn(KoinExperimentalAPI::class)
fun NavGraphBuilder.listStreamsNavGraph(navController: NavHostController) {
composable(HOME_COMPLETE) { nav ->
- BackHandler(true) {}
- if (nav.lifecycle.currentState == Lifecycle.State.STARTED) {
- loadKoinModules(ListStreamModule().module)
+ // BackHandler(true) {}
+
+ rememberKoinModules {
+ listOf(ListStreamModule.module)
}
- ListStreamsScreen(navController = navController,
+
+ ListStreamsScreen(
+ navController = navController,
onNavigateDetailList = { id ->
navController.navigate("${DETAIL}${id}")
},
@@ -34,9 +35,6 @@ fun NavGraphBuilder.listStreamsNavGraph(navController: NavHostController) {
onNavigateSearchScreen = {
navController.navigate(Routes.SEARCH)
},
- disposable = {
- unloadKoinModules(ListStreamModule().module)
- },
profilePicture = nav.arguments?.getString(PROFILE_ID) ?: DEFAULT_ID
)
}
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamViewModel.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamViewModel.kt
similarity index 74%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamViewModel.kt
rename to feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamViewModel.kt
index f470f26f..0c6ad07f 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamViewModel.kt
+++ b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamViewModel.kt
@@ -5,7 +5,6 @@ import androidx.lifecycle.viewModelScope
import androidx.paging.cachedIn
import androidx.paging.map
import com.codandotv.streamplayerapp.core_networking.handleError.catchFailure
-import com.codandotv.streamplayerapp.feature.list.streams.R
import com.codandotv.streamplayerapp.feature_list_streams.core.ContentType
import com.codandotv.streamplayerapp.feature_list_streams.list.domain.GetGenresUseCase
import com.codandotv.streamplayerapp.feature_list_streams.list.domain.GetTopRatedStream
@@ -14,8 +13,8 @@ import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.Genr
import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.HighlightBanner
import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.IconAndTextInfo
import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.Stream
-import com.codandotv.streamplayerapp.feature_list_streams.list.presentation.widgets.StreamsCardContent
-import com.codandotv.streamplayerapp.feature_list_streams.list.presentation.widgets.StreamsCarouselContent
+import com.codandotv.streamplayerapp.core_shared_ui.widget.StreamsCardContent
+import com.codandotv.streamplayerapp.core_shared_ui.widget.StreamsCarouselContent
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.combine
@@ -25,10 +24,17 @@ 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 com.codandotv.streamplayerapp.core.shared.ui.R as SharedUiR
+import streamplayerapp_kmp.core_shared_ui.generated.resources.ic_add
+import streamplayerapp_kmp.core_shared_ui.generated.resources.ic_info
+import streamplayerapp_kmp.core_shared_ui.generated.resources.ic_play
+import streamplayerapp_kmp.feature_list_streams.generated.resources.Res
+import streamplayerapp_kmp.feature_list_streams.generated.resources.ic_top_10
+import streamplayerapp_kmp.core_shared_ui.generated.resources.Res as SharedRes
+import streamplayerapp_kmp.feature_list_streams.generated.resources.list_highlight_banner_add
+import streamplayerapp_kmp.feature_list_streams.generated.resources.list_highlight_banner_info
+import streamplayerapp_kmp.feature_list_streams.generated.resources.list_highlight_banner_stream_ranking
+import streamplayerapp_kmp.feature_list_streams.generated.resources.list_highlight_banner_watch
-@KoinViewModel
class ListStreamViewModel(
private val listStreams: ListStreamUseCase,
private val listGenres: GetGenresUseCase,
@@ -64,7 +70,6 @@ class ListStreamViewModel(
}
.collect { pair ->
val (latest, genres) = pair
-
_uiState.update {
it.copy(
streamsCarouselContent = genres.map { genreTarget ->
@@ -84,23 +89,24 @@ class ListStreamViewModel(
contentType = ContentType.getContentName(ContentType.FILM),
contentTypeAsPlural = ContentType.getContentNameAsPlural(ContentType.FILM),
extraInfo = IconAndTextInfo(
- R.drawable.ic_top_10,
- R.string.list_highlight_banner_stream_ranking
+ Res.drawable.ic_top_10,
+ Res.string.list_highlight_banner_stream_ranking
),
leftButton = IconAndTextInfo(
- SharedUiR.drawable.ic_add,
- R.string.list_highlight_banner_add
+ SharedRes.drawable.ic_add,
+ Res.string.list_highlight_banner_add
),
centralButton = IconAndTextInfo(
- SharedUiR.drawable.ic_play,
- R.string.list_highlight_banner_watch
+ SharedRes.drawable.ic_play,
+ Res.string.list_highlight_banner_watch
),
rightButton = IconAndTextInfo(
- SharedUiR.drawable.ic_info,
- R.string.list_highlight_banner_info
+ SharedRes.drawable.ic_info,
+ Res.string.list_highlight_banner_info
),
)
+
private fun getStreamsByGenre(genre: Genre): StreamsCarouselContent {
return StreamsCarouselContent(
genre.name,
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsScreen.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsScreen.kt
similarity index 79%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsScreen.kt
rename to feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsScreen.kt
index 345d078b..c8691035 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsScreen.kt
+++ b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsScreen.kt
@@ -1,6 +1,5 @@
package com.codandotv.streamplayerapp.feature_list_streams.list.presentation.screens
-import android.annotation.SuppressLint
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -17,25 +16,20 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
-import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.unit.dp
-import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
-import androidx.navigation.compose.rememberNavController
import com.codandotv.streamplayerapp.core_navigation.bottomnavigation.StreamPlayerBottomNavigation
-import com.codandotv.streamplayerapp.core_shared_ui.theme.ThemePreviews
import com.codandotv.streamplayerapp.core_shared_ui.widget.StreamPlayerTopBar
import com.codandotv.streamplayerapp.feature_list_streams.list.presentation.widgets.HighlightBanner
-import com.codandotv.streamplayerapp.feature_list_streams.list.presentation.widgets.StreamsCarousel
-import org.koin.androidx.compose.koinViewModel
+import com.codandotv.streamplayerapp.core_shared_ui.widget.StreamsCarousel
+import org.koin.compose.viewmodel.koinViewModel
@Suppress("LongParameterList")
-@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ListStreamsScreen(
@@ -44,21 +38,13 @@ fun ListStreamsScreen(
onNavigateDetailList: (String) -> Unit = {},
onNavigateProfilePicker: () -> Unit = {},
onNavigateSearchScreen: () -> Unit = {},
- disposable: () -> Unit = {},
profilePicture: String
) {
- val uiState by viewModel.uiState.collectAsStateWithLifecycle()
- val lifecycleOwner = LocalLifecycleOwner.current
+ val uiState by viewModel.uiState.collectAsState()
val scrollBehavior =
TopAppBarDefaults.exitUntilCollapsedScrollBehavior(rememberTopAppBarState())
val baseScrollState = rememberScrollState()
- DisposableEffect(lifecycleOwner) {
- onDispose {
- disposable.invoke()
- }
- }
-
Scaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
@@ -108,8 +94,3 @@ fun ListStreamsScreen(
}
}
-@ThemePreviews
-@Composable
-fun ListStreamsScreenPreview() {
- ListStreamsScreen(navController = rememberNavController(), profilePicture = "")
-}
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsUIState.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsUIState.kt
similarity index 76%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsUIState.kt
rename to feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsUIState.kt
index fba66712..5260d36c 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsUIState.kt
+++ b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/screens/ListStreamsUIState.kt
@@ -1,7 +1,7 @@
package com.codandotv.streamplayerapp.feature_list_streams.list.presentation.screens
import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.HighlightBanner
-import com.codandotv.streamplayerapp.feature_list_streams.list.presentation.widgets.StreamsCarouselContent
+import com.codandotv.streamplayerapp.core_shared_ui.widget.StreamsCarouselContent
data class ListStreamsUIState(
val highlightBanner: HighlightBanner? = null,
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/widgets/HighlightBanner.kt b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/widgets/HighlightBanner.kt
similarity index 71%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/widgets/HighlightBanner.kt
rename to feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/widgets/HighlightBanner.kt
index bbeb30ec..8b411424 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/widgets/HighlightBanner.kt
+++ b/feature-list-streams/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_list_streams/list/presentation/widgets/HighlightBanner.kt
@@ -1,6 +1,5 @@
package com.codandotv.streamplayerapp.feature_list_streams.list.presentation.widgets
-import androidx.annotation.StringRes
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -27,20 +26,30 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
-import coil.compose.AsyncImage
-import com.codandotv.streamplayerapp.core_shared_ui.theme.ThemePreviews
-import com.codandotv.streamplayerapp.feature.list.streams.R
-import com.codandotv.streamplayerapp.feature_list_streams.core.ContentType
+import com.codandotv.streamplayerapp.core_shared_ui.widget.WebImage
import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.HighlightBanner
import com.codandotv.streamplayerapp.feature_list_streams.list.domain.model.IconAndTextInfo
-import com.codandotv.streamplayerapp.core.shared.ui.R as RSharedUI
+import org.jetbrains.compose.resources.StringResource
+import org.jetbrains.compose.resources.painterResource
+import org.jetbrains.compose.resources.stringResource
+import streamplayerapp_kmp.core_shared_ui.generated.resources.ic_add
+import streamplayerapp_kmp.core_shared_ui.generated.resources.ic_info
+import streamplayerapp_kmp.core_shared_ui.generated.resources.ic_netflix
+import streamplayerapp_kmp.core_shared_ui.generated.resources.ic_play
+import streamplayerapp_kmp.core_shared_ui.generated.resources.icon_netflix
+import streamplayerapp_kmp.feature_list_streams.generated.resources.Res
+import streamplayerapp_kmp.feature_list_streams.generated.resources.list_highligh_banner_content
+import streamplayerapp_kmp.feature_list_streams.generated.resources.list_highlight_banner_watch
+import streamplayerapp_kmp.feature_list_streams.generated.resources.list_icon_add
+import streamplayerapp_kmp.feature_list_streams.generated.resources.list_icon_highligh_banner_ranking
+import streamplayerapp_kmp.feature_list_streams.generated.resources.list_icon_info
+import streamplayerapp_kmp.feature_list_streams.generated.resources.list_icon_play
+import streamplayerapp_kmp.core_shared_ui.generated.resources.Res as SharedRes
@Suppress("MagicNumber")
@Composable
@@ -74,11 +83,11 @@ fun HighlightBanner(modifier: Modifier = Modifier, data: HighlightBanner?) {
@Composable
fun ContentImage(modifier: Modifier = Modifier, imageUrl: String) {
- AsyncImage(
+ WebImage(
modifier = modifier.fillMaxSize(),
- model = imageUrl,
+ imageUrl = imageUrl,
contentScale = ContentScale.Crop,
- contentDescription = stringResource(id = R.string.list_highligh_banner_content)
+ contentDescription = stringResource(Res.string.list_highligh_banner_content)
)
}
@@ -115,20 +124,17 @@ fun ContentName(modifier: Modifier = Modifier, name: String) {
fun ContentRanking(
modifier: Modifier = Modifier,
extraInfo: IconAndTextInfo,
- @StringRes contentTypeAsPlural: Int
+ contentTypeAsPlural: StringResource
) {
Row(modifier = modifier, verticalAlignment = Alignment.CenterVertically) {
Icon(
- painter = painterResource(id = extraInfo.icon),
- contentDescription = stringResource(id = R.string.list_icon_highligh_banner_ranking),
+ painter = painterResource(extraInfo.icon),
+ contentDescription = stringResource(Res.string.list_icon_highligh_banner_ranking),
modifier = Modifier.size(24.dp),
tint = Color.Unspecified
)
Text(
- text = stringResource(
- id = extraInfo.text,
- stringResource(contentTypeAsPlural).lowercase()
- ),
+ text = stringResource(contentTypeAsPlural).lowercase(),
Modifier.padding(start = 4.dp),
style = TextStyle(fontWeight = FontWeight.Bold),
fontSize = 14.sp,
@@ -138,11 +144,11 @@ fun ContentRanking(
}
@Composable
-fun ContentType(modifier: Modifier = Modifier, @StringRes contentType: Int) {
+fun ContentType(modifier: Modifier = Modifier, contentType: StringResource) {
Row(modifier = modifier, verticalAlignment = Alignment.CenterVertically) {
Icon(
- painter = painterResource(id = RSharedUI.drawable.ic_netflix),
- contentDescription = stringResource(id = RSharedUI.string.icon_netflix),
+ painter = painterResource(SharedRes.drawable.ic_netflix),
+ contentDescription = stringResource(SharedRes.string.icon_netflix),
modifier = Modifier.size(16.dp),
tint = Color.Unspecified
)
@@ -189,13 +195,13 @@ fun AddToListButton(
IconButton(onClick = { onClick.invoke() }, modifier = modifier) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Icon(
- painter = painterResource(id = RSharedUI.drawable.ic_add),
- contentDescription = stringResource(id = R.string.list_icon_add),
+ painter = painterResource(SharedRes.drawable.ic_add),
+ contentDescription = stringResource(Res.string.list_icon_add),
tint = Color.White,
)
Text(
fontSize = 10.sp,
- text = stringResource(id = data.leftButton.text),
+ text = stringResource(data.leftButton.text),
color = Color.White,
)
}
@@ -211,12 +217,12 @@ fun InfoButton(
IconButton(onClick = { onClick.invoke() }, modifier = modifier) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Icon(
- painter = painterResource(id = RSharedUI.drawable.ic_info),
- contentDescription = stringResource(id = R.string.list_icon_info),
+ painter = painterResource(SharedRes.drawable.ic_info),
+ contentDescription = stringResource(Res.string.list_icon_info),
tint = Color.White
)
Text(
- text = stringResource(id = data.rightButton.text),
+ text = stringResource(data.rightButton.text),
fontSize = 10.sp,
color = Color.White
)
@@ -242,14 +248,14 @@ fun PlayButton(
)
) {
Icon(
- painter = painterResource(RSharedUI.drawable.ic_play),
- contentDescription = stringResource(id = R.string.list_icon_play),
+ painter = painterResource(SharedRes.drawable.ic_play),
+ contentDescription = stringResource(Res.string.list_icon_play),
tint = Color.Black,
modifier = Modifier.padding(vertical = 8.dp)
)
Spacer(modifier = Modifier.width(4.dp))
Text(
- text = stringResource(id = R.string.list_highlight_banner_watch),
+ text = stringResource(Res.string.list_highlight_banner_watch),
color = Color.Black,
fontSize = 14.sp,
modifier = Modifier
@@ -258,23 +264,3 @@ fun PlayButton(
)
}
}
-
-@ThemePreviews
-@Composable
-fun HighlightBannerPreview() {
- HighlightBanner(
- data = HighlightBanner(
- name = stringResource(id = RSharedUI.string.app_name),
- imageUrl = String(),
- contentType = ContentType.getContentName(ContentType.SHOW),
- contentTypeAsPlural = ContentType.getContentNameAsPlural(ContentType.SHOW),
- extraInfo = IconAndTextInfo(
- R.drawable.ic_top_10,
- ContentType.getContentName(ContentType.SHOW)
- ),
- leftButton = IconAndTextInfo(RSharedUI.drawable.ic_add, R.string.list_highlight_banner_add),
- centralButton = IconAndTextInfo(RSharedUI.drawable.ic_play, R.string.list_highlight_banner_watch),
- rightButton = IconAndTextInfo(RSharedUI.drawable.ic_info, R.string.list_highlight_banner_info),
- )
- )
-}
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/core/ContentType.kt b/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/core/ContentType.kt
deleted file mode 100644
index eef6a23b..00000000
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/core/ContentType.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.codandotv.streamplayerapp.feature_list_streams.core
-
-import androidx.annotation.StringRes
-import com.codandotv.streamplayerapp.feature.list.streams.R
-
-enum class ContentType(@StringRes val contentName: Int, @StringRes val contentNameAsPlural: Int) {
- SHOW(R.string.list_content_type_show, R.string.list_content_type_show_plural),
- FILM(R.string.list_content_type_film, R.string.list_content_type_film_plural);
-
- companion object {
- fun getContentName(contentType: ContentType) =
- values().first { contentType == it }.contentName
-
- fun getContentNameAsPlural(contentType: ContentType) =
- values().first { contentType == it }.contentNameAsPlural
- }
-}
\ No newline at end of file
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/data/DetailStreamService.kt b/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/data/DetailStreamService.kt
deleted file mode 100644
index d61f86a4..00000000
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/detail/data/DetailStreamService.kt
+++ /dev/null
@@ -1,15 +0,0 @@
-package com.codandotv.streamplayerapp.feature_list_streams.detail.data
-
-import com.codandotv.streamplayerapp.core_networking.handleError.NetworkResponse
-import com.codandotv.streamplayerapp.feature_list_streams.detail.data.model.DetailStreamResponse
-import com.codandotv.streamplayerapp.feature_list_streams.detail.data.model.VideoStreamsResponse
-import retrofit2.http.GET
-import retrofit2.http.Path
-
-interface DetailStreamService {
- @GET("movie/{movie_id}")
- suspend fun getMovie(@Path("movie_id") movieId: String): NetworkResponse
-
- @GET("movie/{movie_id}/videos")
- suspend fun getVideoStreams(@Path("movie_id") movieId: String): NetworkResponse
-}
\ No newline at end of file
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/data/ListStreamService.kt b/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/data/ListStreamService.kt
deleted file mode 100644
index d702c49e..00000000
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/data/ListStreamService.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.codandotv.streamplayerapp.feature_list_streams.list.data
-
-import com.codandotv.streamplayerapp.core_networking.handleError.NetworkResponse
-import com.codandotv.streamplayerapp.feature_list_streams.list.data.model.GenresResponse
-import com.codandotv.streamplayerapp.feature_list_streams.list.data.model.ListStreamResponse
-import com.codandotv.streamplayerapp.feature_list_streams.list.data.model.StreamResponse
-import retrofit2.http.GET
-import retrofit2.http.Query
-
-interface ListStreamService {
- @GET("discover/movie")
- suspend fun getMovies(@Query("with_genres") genres: String) : NetworkResponse
-
- @GET("discover/movie")
- suspend fun getPaginatedMovies(
- @Query("with_genres") genres: String,
- @Query("page") page: Int
- ) : NetworkResponse
-
- @GET("genre/movie/list")
- suspend fun getGenres(): NetworkResponse
-
- @GET("discover/movie")
- suspend fun getTopRatedMovies(
- @Query("sort_by") sortBy: String = "vote_average.desc",
- @Query("page") page: Int = 1
- ): NetworkResponse
-}
\ No newline at end of file
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/data/model/ListStreamResponse.kt b/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/data/model/ListStreamResponse.kt
deleted file mode 100644
index 0cd75ada..00000000
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/data/model/ListStreamResponse.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.codandotv.streamplayerapp.feature_list_streams.list.data.model
-
-@Suppress("ConstructorParameterNaming")
-data class StreamResponse(
- val id : String,
- val title : String,
- val overview : String,
- val poster_path: String? = null,
-)
-data class ListStreamResponse(
- val results: List
-)
\ No newline at end of file
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/di/ListStreamModule.kt b/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/di/ListStreamModule.kt
deleted file mode 100644
index 9a4ea1ac..00000000
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/list/di/ListStreamModule.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.codandotv.streamplayerapp.feature_list_streams.list.di
-
-import com.codandotv.streamplayerapp.feature_list_streams.list.data.ListStreamService
-import org.koin.core.annotation.ComponentScan
-import org.koin.core.annotation.Factory
-import org.koin.core.annotation.Module
-import org.koin.core.context.GlobalContext
-import retrofit2.Retrofit
-
-@Module
-@ComponentScan("com.codandotv.streamplayerapp.feature_list_streams.list")
-class ListStreamModule {
-
- @Factory
- fun service(): ListStreamService {
- val koin = GlobalContext.get()
- val retrofit = koin.get()
- return retrofit.create(ListStreamService::class.java)
- }
-}
\ No newline at end of file
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/api/MostPopularMoviesService.kt b/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/api/MostPopularMoviesService.kt
deleted file mode 100644
index a2d6e452..00000000
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/api/MostPopularMoviesService.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.codandotv.streamplayerapp.feature_list_streams.search.data.api
-
-import com.codandotv.streamplayerapp.core_networking.handleError.NetworkResponse
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.model.ListSearchStreamResponse
-import retrofit2.http.GET
-
-interface MostPopularMoviesService {
- @GET("movie/popular")
- suspend fun getPopular(): NetworkResponse
-}
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/api/SearchStreamService.kt b/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/api/SearchStreamService.kt
deleted file mode 100644
index c9d43b1d..00000000
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/api/SearchStreamService.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.codandotv.streamplayerapp.feature_list_streams.search.data.api
-
-import com.codandotv.streamplayerapp.core_networking.handleError.NetworkResponse
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.model.ListSearchStreamResponse
-import retrofit2.http.GET
-import retrofit2.http.Query
-
-interface SearchStreamService {
- @GET("search/movie")
- suspend fun getSearch(@Query("query") query: String) : NetworkResponse
-}
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/model/ListSearchStreamResponse.kt b/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/model/ListSearchStreamResponse.kt
deleted file mode 100644
index d15bdc21..00000000
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/model/ListSearchStreamResponse.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.codandotv.streamplayerapp.feature_list_streams.search.data.model
-
-import com.squareup.moshi.Json
-
-data class ListSearchStreamResponse(
- @Json(name = "results")
- val results: List
-) {
- data class SearchStreamResponse(
- @Json(name = "id")
- val id: String,
- @Json(name = "title")
- val title: String,
- @Json(name="overview")
- val overview: String,
- @Json(name = "poster_path")
- val posterPath: String,
- )
-}
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/di/SearchModule.kt b/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/di/SearchModule.kt
deleted file mode 100644
index 44025733..00000000
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/di/SearchModule.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.codandotv.streamplayerapp.feature_list_streams.search.di
-
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.api.SearchStreamService
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.datasource.SearchStreamDataSourceImpl
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.datasource.MostPopularMoviesDataSource
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.datasource.MostPopularMoviesDataSourceImpl
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.repository.MostPopularMoviesRepository
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.repository.MostPopularMoviesRepositoryImpl
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.api.MostPopularMoviesService
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.datasource.SearchStreamDataSource
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.repository.SearchStreamRepository
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.repository.SearchStreamRepositoryImp
-import com.codandotv.streamplayerapp.feature_list_streams.search.domain.MostPopularMoviesUseCase
-import com.codandotv.streamplayerapp.feature_list_streams.search.domain.MostPopularMoviesUseCaseImpl
-import com.codandotv.streamplayerapp.feature_list_streams.search.domain.SearchUseCase
-import com.codandotv.streamplayerapp.feature_list_streams.search.domain.SearchUseCaseImpl
-import com.codandotv.streamplayerapp.feature_list_streams.search.presentation.screens.SearchViewModel
-import org.koin.androidx.viewmodel.dsl.viewModel
-import org.koin.dsl.module
-import retrofit2.Retrofit
-
-object SearchModule {
- val module = module {
- viewModel {
- SearchViewModel(
- searchUseCase = get(),
- mostPopularMoviesUseCase = get()
- )
- }
-
- factory { get().create(SearchStreamService::class.java) }
- factory { get().create(MostPopularMoviesService::class.java) }
-
- factory { MostPopularMoviesUseCaseImpl(repository = get()) }
- factory { MostPopularMoviesDataSourceImpl(service = get()) }
- factory { MostPopularMoviesRepositoryImpl(dataSource = get()) }
-
- factory { SearchUseCaseImpl(repository = get()) }
- factory { SearchStreamDataSourceImpl(service = get()) }
- factory { SearchStreamRepositoryImp(dataSource = get()) }
- }
-}
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/domain/mapper/SearchMapper.kt b/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/domain/mapper/SearchMapper.kt
deleted file mode 100644
index 2817a44b..00000000
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/domain/mapper/SearchMapper.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.codandotv.streamplayerapp.feature_list_streams.search.domain.mapper
-
-import com.codandotv.streamplayerapp.core_networking.Url
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.model.ListSearchStreamResponse.SearchStreamResponse
-import com.codandotv.streamplayerapp.feature_list_streams.search.presentation.widgets.SearchStreamCardModel
-
-fun SearchStreamResponse.toSearchStreamCardModel() = SearchStreamCardModel(
- id = id,
- title = title,
- url = "${Url.IMAGE_URL_SIZE_200}${posterPath}"
-)
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/navigation/SearchStreamNavigation.kt b/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/navigation/SearchStreamNavigation.kt
deleted file mode 100644
index adcec747..00000000
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/navigation/SearchStreamNavigation.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.codandotv.streamplayerapp.feature_list_streams.search.presentation.navigation
-
-import androidx.activity.compose.BackHandler
-import androidx.lifecycle.Lifecycle
-import androidx.navigation.NavGraphBuilder
-import androidx.navigation.NavHostController
-import androidx.navigation.compose.composable
-import com.codandotv.streamplayerapp.core_navigation.routes.Routes
-import com.codandotv.streamplayerapp.feature_list_streams.search.di.SearchModule
-import com.codandotv.streamplayerapp.feature_list_streams.search.presentation.screens.SearchScreen
-import org.koin.core.context.loadKoinModules
-import org.koin.core.context.unloadKoinModules
-
-fun NavGraphBuilder.searchStreamsNavGraph(navController: NavHostController) {
- composable(Routes.SEARCH) { nav ->
- BackHandler(true) {}
- if (nav.lifecycle.currentState == Lifecycle.State.STARTED) {
- loadKoinModules(SearchModule.module)
- }
- SearchScreen(
- navController = navController,
- onNavigateDetailList = { id ->
- navController.navigate("${Routes.DETAIL}${id}")
- },
- disposable = {
- unloadKoinModules(SearchModule.module)
- }
- )
- }
-}
diff --git a/feature-list-streams/src/main/res/drawable/ic_top_10.webp b/feature-list-streams/src/main/res/drawable/ic_top_10.webp
deleted file mode 100644
index e165119d..00000000
Binary files a/feature-list-streams/src/main/res/drawable/ic_top_10.webp and /dev/null differ
diff --git a/feature-list-streams/src/main/res/layout/activity_list_stream.xml b/feature-list-streams/src/main/res/layout/activity_list_stream.xml
deleted file mode 100644
index 5377cc83..00000000
--- a/feature-list-streams/src/main/res/layout/activity_list_stream.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/feature-list-streams/src/main/res/values/content-description.xml b/feature-list-streams/src/main/res/values/content-description.xml
deleted file mode 100644
index 99cae6c4..00000000
--- a/feature-list-streams/src/main/res/values/content-description.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
- Ícone Reprodução
- Ícone adicionar
- Ícone informações
- Poster de conteúdo em destaque
- Ícone top 10
-
\ No newline at end of file
diff --git a/feature-list-streams/src/main/res/values/strings.xml b/feature-list-streams/src/main/res/values/strings.xml
deleted file mode 100644
index beceb11d..00000000
--- a/feature-list-streams/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
- Assistir
- Baixar E1
- Filme
- Minha Lista
- Classificar
- Compartilhar
- Baixar completo
- Pesquisar
- Voltar
-
-
- Série
- Séries
- Filme
- Filmes
-
- Minha lista
- Saiba mais
- Assistir
- Top 1 em %s hoje
-
-
-
- Principais buscas
- Principais buscas
-
-
- Houve um problema ao conectar à Netflix. Tente novamente mais tarde.
- Tente novamente
- Conteúdo não encontrado
-
-
\ No newline at end of file
diff --git a/feature-profile/build.gradle.kts b/feature-profile/build.gradle.kts
index 4695d8f9..c6695c53 100644
--- a/feature-profile/build.gradle.kts
+++ b/feature-profile/build.gradle.kts
@@ -1,28 +1,31 @@
@file:Suppress("UnstableApiUsage")
plugins {
- id("com.streamplayer.android-library")
- id("com.streamplayer.compose")
- alias(libs.plugins.ksp)
+ id("com.streamplayer.kmp-library")
+ alias(libs.plugins.jetbrains.compose)
+ alias(libs.plugins.compose.compiler)
}
-dependencies {
- implementation(projects.coreNetworking)
- implementation(projects.coreNavigation)
- implementation(projects.coreShared)
- implementation(projects.coreSharedUi)
+kotlin {
+ sourceSets {
+ commonMain.dependencies {
+ implementation(projects.coreNetworking)
+ implementation(projects.coreNavigation)
+ implementation(projects.coreShared)
+ implementation(projects.coreSharedUi)
- implementation(libs.bundles.koin)
- implementation(libs.koin.annotations)
- ksp(libs.koin.compiler)
+ implementation(libs.navigation.compose)
- implementation(libs.bundles.networking)
- implementation(libs.bundles.androidSupport)
- implementation(libs.coil)
+ implementation(compose.material3)
+ implementation(compose.ui)
+ implementation(compose.components.resources)
- testImplementation(libs.bundles.test)
-}
+ implementation(libs.ktor.client.content.serialization.json)
+ implementation(libs.ktor.client.content.negotiation)
-ksp {
- arg("KOIN_CONFIG_CHECK","true")
-}
+ implementation(libs.koin.core)
+ implementation(libs.koin.compose)
+ implementation(libs.koin.compose.viewmodel)
+ }
+ }
+}
\ No newline at end of file
diff --git a/feature-profile/src/androidMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/screens/ProfilePickerStreamToolbarPreview.kt b/feature-profile/src/androidMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/screens/ProfilePickerStreamToolbarPreview.kt
new file mode 100644
index 00000000..f26eac1c
--- /dev/null
+++ b/feature-profile/src/androidMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/screens/ProfilePickerStreamToolbarPreview.kt
@@ -0,0 +1,14 @@
+package com.codandotv.streamplayerapp.profile.presentation.screens
+
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.Composable
+import com.codandotv.streamplayerapp.core_shared_ui.theme.ThemePreviews
+import com.codandotv.streamplayerapp.profile.presentation.widget.ProfilePickerStreamToolbar
+
+@ThemePreviews
+@Composable
+fun ProfilePickerStreamToolbarPreview() {
+ MaterialTheme {
+ ProfilePickerStreamToolbar()
+ }
+}
\ No newline at end of file
diff --git a/feature-profile/src/androidMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/screens/SetupProfilePickerScreenPreview.kt b/feature-profile/src/androidMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/screens/SetupProfilePickerScreenPreview.kt
new file mode 100644
index 00000000..363bd326
--- /dev/null
+++ b/feature-profile/src/androidMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/screens/SetupProfilePickerScreenPreview.kt
@@ -0,0 +1,18 @@
+package com.codandotv.streamplayerapp.profile.presentation.screens
+
+import androidx.compose.runtime.Composable
+import com.codandotv.streamplayerapp.core_shared_ui.theme.ThemePreview
+import com.codandotv.streamplayerapp.core_shared_ui.theme.ThemePreviews
+import com.codandotv.streamplayerapp.profile.domain.ProfileStream
+
+@ThemePreviews
+@Composable
+fun SetupProfilePickerScreenPreview() {
+ ThemePreview {
+ SetupProfilePickerScreen(
+ uiState = ProfilePickerStreamsUIState(
+ selectedItem = ProfileStream("1", "Name", ""),
+ )
+ )
+ }
+}
\ No newline at end of file
diff --git a/feature-profile/src/main/res/drawable/image_placeholder.xml b/feature-profile/src/commonMain/composeResources/drawable/image_placeholder.xml
similarity index 100%
rename from feature-profile/src/main/res/drawable/image_placeholder.xml
rename to feature-profile/src/commonMain/composeResources/drawable/image_placeholder.xml
diff --git a/feature-profile/src/main/res/drawable/netflix_horizontal_logo.xml b/feature-profile/src/commonMain/composeResources/drawable/netflix_horizontal_logo.xml
similarity index 100%
rename from feature-profile/src/main/res/drawable/netflix_horizontal_logo.xml
rename to feature-profile/src/commonMain/composeResources/drawable/netflix_horizontal_logo.xml
diff --git a/feature-profile/src/main/res/values/strings.xml b/feature-profile/src/commonMain/composeResources/values/strings.xml
similarity index 100%
rename from feature-profile/src/main/res/values/strings.xml
rename to feature-profile/src/commonMain/composeResources/values/strings.xml
diff --git a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/data/ProfilePickerStreamRepository.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/data/ProfilePickerStreamRepository.kt
similarity index 84%
rename from feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/data/ProfilePickerStreamRepository.kt
rename to feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/data/ProfilePickerStreamRepository.kt
index 7fdba887..793670c5 100644
--- a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/data/ProfilePickerStreamRepository.kt
+++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/data/ProfilePickerStreamRepository.kt
@@ -1,20 +1,17 @@
-package com.codandotv.streamplayerapp.feature_profile.profile.data
+package com.codandotv.streamplayerapp.profile.data
-import android.util.Log
import com.codandotv.streamplayerapp.core_networking.handleError.toFlow
import com.codandotv.streamplayerapp.core_networking.handleError.toResult
-import com.codandotv.streamplayerapp.feature_profile.profile.domain.ProfileStream
-import com.codandotv.streamplayerapp.feature_profile.profile.domain.toProfiles
+import com.codandotv.streamplayerapp.profile.domain.ProfileStream
+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 {
@@ -23,7 +20,7 @@ class ProfilePickerStreamRepositoryImpl(
with(service.getProfiles()) {
if (this.toResult().isFailure || this.toResult().getOrNull() == null) {
- Log.i("ProfilePickerStreamRepositoryImpl", "versão off carregada")
+ // Log.i("ProfilePickerStreamRepositoryImpl", "versão off carregada")
return flowOf(mockProfiles)
} else {
return this.toFlow().map { it.toProfiles() }
diff --git a/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/data/ProfilePickerStreamService.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/data/ProfilePickerStreamService.kt
new file mode 100644
index 00000000..e071ddf2
--- /dev/null
+++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/data/ProfilePickerStreamService.kt
@@ -0,0 +1,20 @@
+package com.codandotv.streamplayerapp.profile.data
+
+import com.codandotv.streamplayerapp.core_networking.handleError.NetworkResponse
+import com.codandotv.streamplayerapp.core_networking.handleError.safeRequest
+import com.codandotv.streamplayerapp.profile.data.model.ProfilesResponse
+import io.ktor.client.HttpClient
+import io.ktor.client.request.url
+
+interface ProfilePickerStreamService {
+ suspend fun getProfiles(): NetworkResponse
+}
+
+class ProfilePickerStreamServiceImpl(
+ private val client: HttpClient
+) : ProfilePickerStreamService {
+ override suspend fun getProfiles(): NetworkResponse =
+ client.safeRequest {
+ url("profiles")
+ }
+}
diff --git a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/data/model/ProfileStreamResponse.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/data/model/ProfileStreamResponse.kt
similarity index 63%
rename from feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/data/model/ProfileStreamResponse.kt
rename to feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/data/model/ProfileStreamResponse.kt
index b8534939..afac8e93 100644
--- a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/data/model/ProfileStreamResponse.kt
+++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/data/model/ProfileStreamResponse.kt
@@ -1,5 +1,8 @@
-package com.codandotv.streamplayerapp.feature_profile.profile.data.model
+package com.codandotv.streamplayerapp.profile.data.model
+import kotlinx.serialization.Serializable
+
+@Serializable
@Suppress("ConstructorParameterNaming")
data class ProfileStreamResponse(
val id: String,
@@ -7,6 +10,7 @@ data class ProfileStreamResponse(
val profile_url: String,
)
+@Serializable
data class ProfilesResponse(
val profiles: List
)
\ No newline at end of file
diff --git a/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/di/ProfilePickerStreamModule.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/di/ProfilePickerStreamModule.kt
new file mode 100644
index 00000000..127e6887
--- /dev/null
+++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/di/ProfilePickerStreamModule.kt
@@ -0,0 +1,39 @@
+package com.codandotv.streamplayerapp.profile.di
+
+import com.codandotv.streamplayerapp.profile.data.ProfilePickerStreamRepository
+import com.codandotv.streamplayerapp.profile.data.ProfilePickerStreamRepositoryImpl
+import com.codandotv.streamplayerapp.profile.data.ProfilePickerStreamService
+import com.codandotv.streamplayerapp.profile.data.ProfilePickerStreamServiceImpl
+import com.codandotv.streamplayerapp.profile.domain.ProfilePickerStreamUseCase
+import com.codandotv.streamplayerapp.profile.domain.ProfilePickerStreamUseCaseImpl
+import com.codandotv.streamplayerapp.profile.presentation.screens.ProfilePickerStreamViewModel
+import org.koin.core.module.dsl.viewModel
+import org.koin.dsl.module
+
+object ProfilePickerStreamModule {
+ val module = module {
+ viewModel {
+ ProfilePickerStreamViewModel(
+ useCase = get()
+ )
+ }
+
+ factory {
+ ProfilePickerStreamUseCaseImpl(
+ profilePickerStreamRepository = get()
+ )
+ }
+
+ factory {
+ ProfilePickerStreamRepositoryImpl(
+ service = get()
+ )
+ }
+
+ factory {
+ ProfilePickerStreamServiceImpl(
+ client = get()
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/domain/ProfilePickerStreamMapper.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/domain/ProfilePickerStreamMapper.kt
similarity index 60%
rename from feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/domain/ProfilePickerStreamMapper.kt
rename to feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/domain/ProfilePickerStreamMapper.kt
index 6d5ce0ac..ff732549 100644
--- a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/domain/ProfilePickerStreamMapper.kt
+++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/domain/ProfilePickerStreamMapper.kt
@@ -1,6 +1,6 @@
-package com.codandotv.streamplayerapp.feature_profile.profile.domain
+package com.codandotv.streamplayerapp.profile.domain
-import com.codandotv.streamplayerapp.feature_profile.profile.data.model.ProfilesResponse
+import com.codandotv.streamplayerapp.profile.data.model.ProfilesResponse
fun ProfilesResponse.toProfiles(): List = this.profiles.map { profileResponse ->
ProfileStream(
diff --git a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/domain/ProfilePickerStreamUseCase.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/domain/ProfilePickerStreamUseCase.kt
similarity index 91%
rename from feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/domain/ProfilePickerStreamUseCase.kt
rename to feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/domain/ProfilePickerStreamUseCase.kt
index 225a15be..abf1a4a6 100644
--- a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/domain/ProfilePickerStreamUseCase.kt
+++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/domain/ProfilePickerStreamUseCase.kt
@@ -1,9 +1,8 @@
@file:Suppress("MagicNumber")
-package com.codandotv.streamplayerapp.feature_profile.profile.domain
+package com.codandotv.streamplayerapp.profile.domain
-import com.codandotv.streamplayerapp.feature_profile.profile.data.ProfilePickerStreamRepository
+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/main/java/com/codandotv/streamplayerapp/feature_profile/profile/domain/ProfileStream.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/domain/ProfileStream.kt
similarity index 57%
rename from feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/domain/ProfileStream.kt
rename to feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/domain/ProfileStream.kt
index 7c365999..5440084a 100644
--- a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/domain/ProfileStream.kt
+++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/domain/ProfileStream.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp.feature_profile.profile.domain
+package com.codandotv.streamplayerapp.profile.domain
data class ProfileStream(
val id: String,
diff --git a/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/navigation/ProfilePickerStreamNavigation.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/navigation/ProfilePickerStreamNavigation.kt
new file mode 100644
index 00000000..eb885448
--- /dev/null
+++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/navigation/ProfilePickerStreamNavigation.kt
@@ -0,0 +1,26 @@
+package com.codandotv.streamplayerapp.profile.presentation.navigation
+
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.NavHostController
+import androidx.navigation.compose.composable
+import com.codandotv.streamplayerapp.core_navigation.routes.BottomNavRoutes.HOME
+import com.codandotv.streamplayerapp.core_navigation.routes.BottomNavRoutes.PARAM.PROFILE_ID
+import com.codandotv.streamplayerapp.core_navigation.routes.Routes
+import com.codandotv.streamplayerapp.profile.di.ProfilePickerStreamModule
+import com.codandotv.streamplayerapp.profile.presentation.screens.ProfilePickerStreamScreen
+import org.koin.compose.module.rememberKoinModules
+import org.koin.core.annotation.KoinExperimentalAPI
+
+@OptIn(KoinExperimentalAPI::class)
+fun NavGraphBuilder.profilePickerStreamNavGraph(navController: NavHostController) {
+ composable(Routes.PROFILE_PICKER) {
+ rememberKoinModules {
+ listOf(ProfilePickerStreamModule.module)
+ }
+ ProfilePickerStreamScreen(
+ onNavigateListStreams = { profilePic ->
+ navController.navigate("$HOME?$PROFILE_ID=$profilePic")
+ }
+ )
+ }
+}
diff --git a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/screens/ProfilePickerStreamScreen.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/screens/ProfilePickerStreamScreen.kt
similarity index 65%
rename from feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/screens/ProfilePickerStreamScreen.kt
rename to feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/screens/ProfilePickerStreamScreen.kt
index e54b0442..5dfa8488 100644
--- a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/screens/ProfilePickerStreamScreen.kt
+++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/screens/ProfilePickerStreamScreen.kt
@@ -1,47 +1,41 @@
-package com.codandotv.streamplayerapp.feature_profile.profile.presentation.screens
+package com.codandotv.streamplayerapp.profile.presentation.screens
-import android.annotation.SuppressLint
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.animateIntOffsetAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
-import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.platform.LocalLifecycleOwner
-import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import com.codandotv.streamplayerapp.core_shared_ui.theme.ThemePreview
-import com.codandotv.streamplayerapp.core_shared_ui.theme.ThemePreviews
-import com.codandotv.streamplayerapp.feature.profile.R
-import com.codandotv.streamplayerapp.feature_profile.profile.domain.ProfileStream
-import com.codandotv.streamplayerapp.feature_profile.profile.presentation.widget.LoadScreen
-import com.codandotv.streamplayerapp.feature_profile.profile.presentation.widget.ProfilePickerOpacityLayer
-import com.codandotv.streamplayerapp.feature_profile.profile.presentation.widget.ProfilePickerProfilesGrid
-import com.codandotv.streamplayerapp.feature_profile.profile.presentation.widget.ProfilePickerSelectedProfileContainer
-import com.codandotv.streamplayerapp.feature_profile.profile.presentation.widget.ProfilePickerStreamToolbar
-import com.codandotv.streamplayerapp.feature_profile.profile.presentation.widget.dpToPx
-import org.koin.androidx.compose.koinViewModel
+import com.codandotv.streamplayerapp.profile.domain.ProfileStream
+import com.codandotv.streamplayerapp.profile.presentation.widget.LoadScreen
+import com.codandotv.streamplayerapp.profile.presentation.widget.ProfilePickerOpacityLayer
+import com.codandotv.streamplayerapp.profile.presentation.widget.ProfilePickerProfilesGrid
+import com.codandotv.streamplayerapp.profile.presentation.widget.ProfilePickerSelectedProfileContainer
+import com.codandotv.streamplayerapp.profile.presentation.widget.ProfilePickerStreamToolbar
+import com.codandotv.streamplayerapp.profile.presentation.widget.dpToPx
+import org.jetbrains.compose.resources.stringResource
+import org.koin.compose.viewmodel.koinViewModel
+import streamplayerapp_kmp.feature_profile.generated.resources.Res
+import streamplayerapp_kmp.feature_profile.generated.resources.profile_animation_background_opacity
+import streamplayerapp_kmp.feature_profile.generated.resources.profile_animation_selected_image_position
+import streamplayerapp_kmp.feature_profile.generated.resources.profile_animation_selected_image_size
+import streamplayerapp_kmp.feature_profile.generated.resources.profile_animation_showing_all_profiles
@Composable
fun ProfilePickerStreamScreen(
viewModel: ProfilePickerStreamViewModel = koinViewModel(),
onNavigateListStreams: (String) -> Unit = {},
- disposable: () -> Unit = {}
) {
- val uiState by viewModel.uiState.collectAsStateWithLifecycle()
- val lifecycleOwner = LocalLifecycleOwner.current
- Lifecycle(lifecycleOwner, viewModel, disposable)
+ val uiState by viewModel.uiState.collectAsState()
if (uiState.isLoading) {
LoadScreen()
@@ -62,10 +56,8 @@ fun ProfilePickerStreamScreen(
}
@Suppress("LongMethod", "LongParameterList")
-@OptIn(ExperimentalMaterial3Api::class)
-@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@Composable
-private fun SetupProfilePickerScreen(
+fun SetupProfilePickerScreen(
uiState: ProfilePickerStreamsUIState,
onSetCenterImageAlpha: (Float) -> Unit = {},
onSetScreenSize: (Float, Float, Int, Int) -> Unit = { _, _, _, _ -> },
@@ -81,7 +73,7 @@ private fun SetupProfilePickerScreen(
} else {
Color.Transparent
},
- label = stringResource(R.string.profile_animation_background_opacity),
+ label = stringResource(Res.string.profile_animation_background_opacity),
animationSpec = tween(durationMillis = 1000),
finishedListener = {
onSetCenterImageAlpha(0f)
@@ -109,13 +101,13 @@ private fun SetupProfilePickerScreen(
// Preparing animations
val animatedSizeImage by animateDpAsState(
targetValue = if (expandImage) expandedImageSize.dp else defaultImageSize.dp,
- label = stringResource(R.string.profile_animation_selected_image_size),
+ label = stringResource(Res.string.profile_animation_selected_image_size),
animationSpec = tween(durationMillis = 1000),
)
val animatedProfileAlpha: Float by animateFloatAsState(
if (lastItemPositioned) 1f else 0f,
- label = stringResource(R.string.profile_animation_showing_all_profiles),
+ label = stringResource(Res.string.profile_animation_showing_all_profiles),
)
val animatedOffsetSelectedProfileImage by animateIntOffsetAsState(
@@ -130,7 +122,7 @@ private fun SetupProfilePickerScreen(
IntOffset(0, 0)
}
},
- label = stringResource(R.string.profile_animation_selected_image_position),
+ label = stringResource(Res.string.profile_animation_selected_image_position),
animationSpec = tween(durationMillis = if (!showCenterImage) 100 else 800)
)
@@ -152,32 +144,4 @@ private fun SetupProfilePickerScreen(
}
}
)
-}
-
-@Composable
-private fun Lifecycle(
- lifecycleOwner: LifecycleOwner, viewModel: ProfilePickerStreamViewModel, disposable: () -> Unit
-) {
- DisposableEffect(lifecycleOwner) {
- val lifecycle = lifecycleOwner.lifecycle
-
- lifecycle.addObserver(viewModel)
-
- onDispose {
- lifecycle.removeObserver(viewModel)
- disposable.invoke()
- }
- }
-}
-
-@ThemePreviews
-@Composable
-fun SetupProfilePickerScreenPreview() {
- ThemePreview {
- SetupProfilePickerScreen(
- uiState = ProfilePickerStreamsUIState(
- selectedItem = ProfileStream("1", "Name", ""),
- )
- )
- }
}
\ No newline at end of file
diff --git a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/screens/ProfilePickerStreamViewModel.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/screens/ProfilePickerStreamViewModel.kt
similarity index 88%
rename from feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/screens/ProfilePickerStreamViewModel.kt
rename to feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/screens/ProfilePickerStreamViewModel.kt
index 36e3aa90..1eac734f 100644
--- a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/screens/ProfilePickerStreamViewModel.kt
+++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/screens/ProfilePickerStreamViewModel.kt
@@ -1,24 +1,20 @@
-package com.codandotv.streamplayerapp.feature_profile.profile.presentation.screens
+package com.codandotv.streamplayerapp.profile.presentation.screens
-import androidx.lifecycle.DefaultLifecycleObserver
-import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.codandotv.streamplayerapp.core_networking.handleError.catchFailure
-import com.codandotv.streamplayerapp.feature_profile.profile.domain.ProfilePickerStreamUseCase
-import com.codandotv.streamplayerapp.feature_profile.profile.domain.ProfileStream
+import com.codandotv.streamplayerapp.profile.domain.ProfilePickerStreamUseCase
+import com.codandotv.streamplayerapp.profile.domain.ProfileStream
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
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 {
+) : ViewModel() {
private val _uiState = MutableStateFlow(ProfilePickerStreamsUIState())
val uiState = _uiState.stateIn(
@@ -27,9 +23,7 @@ class ProfilePickerStreamViewModel(
initialValue = _uiState.value
)
- override fun onCreate(owner: LifecycleOwner) {
- super.onCreate(owner)
-
+ init {
viewModelScope.launch {
useCase.getProfile()
.catchFailure {
diff --git a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/screens/ProfilePickerStreamsUIState.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/screens/ProfilePickerStreamsUIState.kt
similarity index 83%
rename from feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/screens/ProfilePickerStreamsUIState.kt
rename to feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/screens/ProfilePickerStreamsUIState.kt
index 414b8d83..0ca2751b 100644
--- a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/screens/ProfilePickerStreamsUIState.kt
+++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/screens/ProfilePickerStreamsUIState.kt
@@ -1,6 +1,6 @@
-package com.codandotv.streamplayerapp.feature_profile.profile.presentation.screens
+package com.codandotv.streamplayerapp.profile.presentation.screens
-import com.codandotv.streamplayerapp.feature_profile.profile.domain.ProfileStream
+import com.codandotv.streamplayerapp.profile.domain.ProfileStream
data class ProfilePickerStreamsUIState(
diff --git a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/widget/ComposeExtensions.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/widget/ComposeExtensions.kt
similarity index 72%
rename from feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/widget/ComposeExtensions.kt
rename to feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/widget/ComposeExtensions.kt
index 2d30f8c5..109a6561 100644
--- a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/widget/ComposeExtensions.kt
+++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/widget/ComposeExtensions.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp.feature_profile.profile.presentation.widget
+package com.codandotv.streamplayerapp.profile.presentation.widget
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalDensity
diff --git a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/widget/ProfilePickerOpacityLayer.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/widget/ProfilePickerOpacityLayer.kt
similarity index 84%
rename from feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/widget/ProfilePickerOpacityLayer.kt
rename to feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/widget/ProfilePickerOpacityLayer.kt
index f8fb3601..efbd403f 100644
--- a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/widget/ProfilePickerOpacityLayer.kt
+++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/widget/ProfilePickerOpacityLayer.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp.feature_profile.profile.presentation.widget
+package com.codandotv.streamplayerapp.profile.presentation.widget
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
diff --git a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/widget/ProfilePickerProfilesGrid.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/widget/ProfilePickerProfilesGrid.kt
similarity index 79%
rename from feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/widget/ProfilePickerProfilesGrid.kt
rename to feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/widget/ProfilePickerProfilesGrid.kt
index f24737a2..d207b644 100644
--- a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/widget/ProfilePickerProfilesGrid.kt
+++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/widget/ProfilePickerProfilesGrid.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp.feature_profile.profile.presentation.widget
+package com.codandotv.streamplayerapp.profile.presentation.widget
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.BoxWithConstraints
@@ -18,14 +18,17 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.graphicsLayer
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
-import coil.compose.AsyncImage
-import com.codandotv.streamplayerapp.feature.profile.R
-import com.codandotv.streamplayerapp.feature_profile.profile.domain.ProfileStream
-import com.codandotv.streamplayerapp.feature_profile.profile.presentation.screens.ProfilePickerStreamsUIState
+import com.codandotv.streamplayerapp.core_shared_ui.widget.WebImage
+import com.codandotv.streamplayerapp.profile.domain.ProfileStream
+import com.codandotv.streamplayerapp.profile.presentation.screens.ProfilePickerStreamsUIState
+import org.jetbrains.compose.resources.painterResource
+import org.jetbrains.compose.resources.stringResource
+import streamplayerapp_kmp.feature_profile.generated.resources.Res
+import streamplayerapp_kmp.feature_profile.generated.resources.image_placeholder
+import streamplayerapp_kmp.feature_profile.generated.resources.profile_current_profile_name
@Composable
fun ProfilePickerProfilesGrid(
@@ -90,13 +93,14 @@ private fun ProfileItem(
profileItemPosition
}
) {
- AsyncImage(
- model = profile.imageUrl,
- placeholder = painterResource(id = R.drawable.image_placeholder),
+ WebImage(
+ imageUrl = profile.imageUrl,
+ //placeholder = painterResource(Res.drawable.image_placeholder),
contentDescription = stringResource(
- id = R.string.profile_current_profile_name,
+ Res.string.profile_current_profile_name,
profile.name
),
+ contentScale = ContentScale.Fit,
modifier = Modifier
.clip(RoundedCornerShape(5))
.alpha(if (selectedItem == profile) selectedImageAlpha else 1f)
diff --git a/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/widget/ProfilePickerSelectedProfileContainer.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/widget/ProfilePickerSelectedProfileContainer.kt
new file mode 100644
index 00000000..652b8181
--- /dev/null
+++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/widget/ProfilePickerSelectedProfileContainer.kt
@@ -0,0 +1,65 @@
+package com.codandotv.streamplayerapp.profile.presentation.widget
+
+import androidx.compose.foundation.layout.BoxWithConstraints
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.offset
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.alpha
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.dp
+import com.codandotv.streamplayerapp.core_shared_ui.widget.WebImage
+import com.codandotv.streamplayerapp.profile.presentation.screens.ProfilePickerStreamsUIState
+
+@Suppress("MagicNumber")
+@Composable
+fun ProfilePickerSelectedProfileContainer(
+ state: ProfilePickerStreamsUIState,
+ offsetSelectedProfileImage: IntOffset,
+ animatedSizeImage: Dp
+) {
+ with(state) {
+ BoxWithConstraints(
+ Modifier
+ .fillMaxSize()
+ .padding(top = 100.dp)
+ ) {
+ if (showCenterImage) {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier
+ .offset { offsetSelectedProfileImage }
+ ) {
+ selectedItem?.imageUrl?.let { imageUrl ->
+ WebImage(
+ imageUrl =imageUrl, /*ImageRequest.Builder(LocalPlatformContext.current)
+ .data(selectedItem?.imageUrl)
+ .crossfade(true)
+ .build()*/
+ contentScale = ContentScale.Fit,
+ contentDescription = null,
+ //placeholder = painterResource(Res.drawable.image_placeholder),
+ /*contentDescription = selectedItem?.let {
+ stringResource(
+ Res.string.profile_current_profile_name,
+ ).format(it.name)
+ },*/
+ modifier = Modifier
+ .clip(RoundedCornerShape(5))
+ .size(animatedSizeImage)
+ .alpha(centerImageAlpha)
+ )
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/widget/ProfilePickerStreamLoad.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/widget/ProfilePickerStreamLoad.kt
similarity index 85%
rename from feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/widget/ProfilePickerStreamLoad.kt
rename to feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/widget/ProfilePickerStreamLoad.kt
index 7c2bc50d..a2746cbd 100644
--- a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/widget/ProfilePickerStreamLoad.kt
+++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/widget/ProfilePickerStreamLoad.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp.feature_profile.profile.presentation.widget
+package com.codandotv.streamplayerapp.profile.presentation.widget
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
diff --git a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/widget/ProfilePickerStreamToolbar.kt b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/widget/ProfilePickerStreamToolbar.kt
similarity index 76%
rename from feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/widget/ProfilePickerStreamToolbar.kt
rename to feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/widget/ProfilePickerStreamToolbar.kt
index 50a2c455..32ef6ca5 100644
--- a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/widget/ProfilePickerStreamToolbar.kt
+++ b/feature-profile/src/commonMain/kotlin/com/codandotv/streamplayerapp/profile/presentation/widget/ProfilePickerStreamToolbar.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp.feature_profile.profile.presentation.widget
+package com.codandotv.streamplayerapp.profile.presentation.widget
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
@@ -14,10 +14,10 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
-import com.codandotv.streamplayerapp.core_shared_ui.theme.ThemePreviews
-import com.codandotv.streamplayerapp.feature.profile.R
+import org.jetbrains.compose.resources.painterResource
+import streamplayerapp_kmp.feature_profile.generated.resources.Res
+import streamplayerapp_kmp.feature_profile.generated.resources.netflix_horizontal_logo
@Composable
fun ProfilePickerStreamToolbar(modifier: Modifier = Modifier) {
@@ -34,7 +34,7 @@ fun ProfilePickerStreamToolbar(modifier: Modifier = Modifier) {
horizontalArrangement = Arrangement.Center
) {
Image(
- painter = painterResource(id = R.drawable.netflix_horizontal_logo),
+ painter = painterResource(Res.drawable.netflix_horizontal_logo),
contentDescription = null,
modifier = Modifier
.height(28.dp)
@@ -56,12 +56,3 @@ fun ProfilePickerStreamToolbar(modifier: Modifier = Modifier) {
.height(56.dp)
)
}
-
-
-@ThemePreviews
-@Composable
-fun ProfilePickerStreamToolbarPreview() {
- MaterialTheme {
- ProfilePickerStreamToolbar()
- }
-}
\ No newline at end of file
diff --git a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/data/ProfilePickerStreamService.kt b/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/data/ProfilePickerStreamService.kt
deleted file mode 100644
index 6c512286..00000000
--- a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/data/ProfilePickerStreamService.kt
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.codandotv.streamplayerapp.feature_profile.profile.data
-
-import com.codandotv.streamplayerapp.core_networking.handleError.NetworkResponse
-import com.codandotv.streamplayerapp.feature_profile.profile.data.model.ProfilesResponse
-import retrofit2.http.GET
-
-interface ProfilePickerStreamService {
- @GET("profiles")
- suspend fun getProfiles(): NetworkResponse
-}
\ No newline at end of file
diff --git a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/di/ProfilePickerStreamModule.kt b/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/di/ProfilePickerStreamModule.kt
deleted file mode 100644
index d6ae9651..00000000
--- a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/di/ProfilePickerStreamModule.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.codandotv.streamplayerapp.feature_profile.profile.di
-
-import com.codandotv.streamplayerapp.core_networking.di.QualifierProfileRetrofit
-import com.codandotv.streamplayerapp.feature_profile.profile.data.ProfilePickerStreamService
-import org.koin.core.annotation.ComponentScan
-import org.koin.core.annotation.Factory
-import org.koin.core.annotation.Module
-import org.koin.core.context.GlobalContext
-import retrofit2.Retrofit
-
-@Module
-@ComponentScan("com.codandotv.streamplayerapp.feature_profile")
-class ProfilePickerStreamModule {
-
- @Factory
- fun service(): ProfilePickerStreamService {
- val koin = GlobalContext.get()
- val retrofit = koin.get(QualifierProfileRetrofit)
- return retrofit.create(ProfilePickerStreamService::class.java)
- }
-
-}
diff --git a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/navigation/ProfilePickerStreamNavigation.kt b/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/navigation/ProfilePickerStreamNavigation.kt
deleted file mode 100644
index 3624f939..00000000
--- a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/navigation/ProfilePickerStreamNavigation.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-package com.codandotv.streamplayerapp.feature_profile.profile.presentation.navigation
-
-import androidx.lifecycle.Lifecycle
-import androidx.navigation.NavGraphBuilder
-import androidx.navigation.NavHostController
-import androidx.navigation.compose.composable
-import com.codandotv.streamplayerapp.core_navigation.routes.BottomNavRoutes.HOME
-import com.codandotv.streamplayerapp.core_navigation.routes.BottomNavRoutes.PARAM.PROFILE_ID
-import com.codandotv.streamplayerapp.core_navigation.routes.Routes
-import com.codandotv.streamplayerapp.feature_profile.profile.di.ProfilePickerStreamModule
-import com.codandotv.streamplayerapp.feature_profile.profile.presentation.screens.ProfilePickerStreamScreen
-import org.koin.core.context.loadKoinModules
-import org.koin.core.context.unloadKoinModules
-import org.koin.ksp.generated.module
-
-fun NavGraphBuilder.profilePickerStreamNavGraph(navController: NavHostController) {
- composable(Routes.PROFILE_PICKER) { nav ->
- if (nav.lifecycle.currentState == Lifecycle.State.STARTED) {
- loadKoinModules(ProfilePickerStreamModule().module)
- }
- ProfilePickerStreamScreen(
- onNavigateListStreams = { profilePic ->
- navController.navigate("$HOME?$PROFILE_ID=$profilePic")
- }
- ) {
- unloadKoinModules(ProfilePickerStreamModule().module)
- }
- }
-}
diff --git a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/widget/ProfilePickerSelectedProfileContainer.kt b/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/widget/ProfilePickerSelectedProfileContainer.kt
deleted file mode 100644
index beade0ac..00000000
--- a/feature-profile/src/main/java/com/codandotv/streamplayerapp/feature_profile/profile/presentation/widget/ProfilePickerSelectedProfileContainer.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-package com.codandotv.streamplayerapp.feature_profile.profile.presentation.widget
-
-import androidx.compose.foundation.layout.BoxWithConstraints
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.offset
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.alpha
-import androidx.compose.ui.draw.clip
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.IntOffset
-import androidx.compose.ui.unit.dp
-import coil.compose.AsyncImage
-import coil.request.ImageRequest
-import com.codandotv.streamplayerapp.feature.profile.R
-import com.codandotv.streamplayerapp.feature_profile.profile.presentation.screens.ProfilePickerStreamsUIState
-
-@Suppress("MagicNumber")
-@Composable
-fun ProfilePickerSelectedProfileContainer(
- state: ProfilePickerStreamsUIState,
- offsetSelectedProfileImage: IntOffset,
- animatedSizeImage: Dp
-) {
- with(state) {
- BoxWithConstraints(
- Modifier
- .fillMaxSize()
- .padding(top = 100.dp)
- ) {
- if (showCenterImage) {
- Column(
- horizontalAlignment = Alignment.CenterHorizontally,
- modifier = Modifier
- .offset { offsetSelectedProfileImage }
- ) {
- AsyncImage(
- model = ImageRequest.Builder(LocalContext.current)
- .data(selectedItem?.imageUrl)
- .crossfade(true)
- .build(),
- placeholder = painterResource(id = R.drawable.image_placeholder),
- contentDescription = selectedItem?.let {
- stringResource(
- id = R.string.profile_current_profile_name,
- it.name
- )
- },
- modifier = Modifier
- .clip(RoundedCornerShape(5))
- .size(animatedSizeImage)
- .alpha(centerImageAlpha)
- )
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/feature-search/.gitignore b/feature-search/.gitignore
new file mode 100644
index 00000000..581f8daa
--- /dev/null
+++ b/feature-search/.gitignore
@@ -0,0 +1 @@
+**/build/**
\ No newline at end of file
diff --git a/feature-search/build.gradle.kts b/feature-search/build.gradle.kts
new file mode 100644
index 00000000..c7562960
--- /dev/null
+++ b/feature-search/build.gradle.kts
@@ -0,0 +1,39 @@
+@file:Suppress("UnstableApiUsage")
+
+plugins {
+ id("com.streamplayer.kmp-library")
+ alias(libs.plugins.jetbrains.compose)
+ alias(libs.plugins.compose.compiler)
+}
+
+kotlin {
+ sourceSets {
+ androidMain.dependencies {
+ implementation(compose.preview)
+ }
+
+ commonMain.dependencies {
+ implementation(libs.paging.compose)
+
+ implementation(projects.coreNetworking)
+ implementation(projects.coreNavigation)
+ implementation(projects.coreShared)
+ implementation(projects.coreSharedUi)
+ implementation(projects.coreLocalStorage)
+
+ implementation(compose.components.resources)
+ implementation(compose.material3)
+ implementation(compose.ui)
+
+
+ implementation(libs.navigation.compose)
+
+ implementation(libs.ktor.client.content.serialization.json)
+ implementation(libs.ktor.client.content.negotiation)
+
+ implementation(libs.koin.core)
+ implementation(libs.koin.compose)
+ implementation(libs.koin.compose.viewmodel)
+ }
+ }
+}
\ No newline at end of file
diff --git a/feature-search/src/androidMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/widgets/SearchStreamCardPreview.kt b/feature-search/src/androidMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/widgets/SearchStreamCardPreview.kt
new file mode 100644
index 00000000..2597746e
--- /dev/null
+++ b/feature-search/src/androidMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/widgets/SearchStreamCardPreview.kt
@@ -0,0 +1,25 @@
+package com.codandotv.streamplayerapp.feature_search.presentation.widgets
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import com.codandotv.streamplayerapp.core_shared_ui.theme.ThemePreviews
+
+
+@ThemePreviews
+@Composable
+fun SearchStreamCardPreview() {
+ SearchStreamCard(
+ content = SearchStreamCardModel(
+ id = "1",
+ title = "The Witcher",
+ url = "https://image.tmdb.org/t/p/w200/iwsMu0ehRPbtaSxqiaUDQB9qMWT.jpg"
+ ),
+ onSearchStreamPressed = {}
+ )
+}
+
+@ThemePreviews
+@Composable
+fun PlayerPreview() {
+ PlayerIcon(modifier = Modifier)
+}
\ No newline at end of file
diff --git a/feature-search/src/androidMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/widgets/SearchStreamsPreview.kt b/feature-search/src/androidMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/widgets/SearchStreamsPreview.kt
new file mode 100644
index 00000000..8b37e056
--- /dev/null
+++ b/feature-search/src/androidMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/widgets/SearchStreamsPreview.kt
@@ -0,0 +1,36 @@
+package com.codandotv.streamplayerapp.feature_search.presentation.widgets
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.tooling.preview.Preview
+
+@Composable
+@Preview
+fun SearchBarPreview() {
+ StreamPlayerTopBar(
+ onBackPressed = {}
+ )
+}
+
+@Composable
+@Preview
+fun SearchTopBarEmptyPreview() {
+ SearchTopBar(
+ currentSearchText = "",
+ onSearchTextChanged = {},
+ onSearchDispatched = {},
+ onCleanTextPressed = {},
+ onSearchIconPressed = {}
+ )
+}
+
+@Composable
+@Preview
+fun SearchTopBarPreview() {
+ SearchTopBar(
+ currentSearchText = "Texto de busca",
+ onSearchTextChanged = {},
+ onSearchDispatched = {},
+ onCleanTextPressed = {},
+ onSearchIconPressed = {}
+ )
+}
diff --git a/feature-search/src/androidMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/widgets/StreamsCarouselPreview.kt b/feature-search/src/androidMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/widgets/StreamsCarouselPreview.kt
new file mode 100644
index 00000000..75b34df3
--- /dev/null
+++ b/feature-search/src/androidMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/widgets/StreamsCarouselPreview.kt
@@ -0,0 +1,19 @@
+package com.codandotv.streamplayerapp.feature_search.presentation.widgets
+
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.tooling.preview.Preview
+
+@Composable
+@Preview
+fun StreamsErrorPreview() {
+ StreamsError(
+ onRetry = {},
+ onCloseButton = {}
+ )
+}
+
+@Composable
+@Preview
+fun StreamEmptyPreview() {
+ StreamsEmpty()
+}
\ No newline at end of file
diff --git a/feature-search/src/commonMain/composeResources/values/strings.xml b/feature-search/src/commonMain/composeResources/values/strings.xml
new file mode 100644
index 00000000..e8445742
--- /dev/null
+++ b/feature-search/src/commonMain/composeResources/values/strings.xml
@@ -0,0 +1,12 @@
+
+
+
+ Principais buscas
+ Principais buscas
+ Voltar
+
+
+ Houve um problema ao conectar à Netflix. Tente novamente mais tarde.
+ Tente novamente
+ Conteúdo não encontrado
+
\ No newline at end of file
diff --git a/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/api/MostPopularMoviesService.kt b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/api/MostPopularMoviesService.kt
new file mode 100644
index 00000000..aa4ac25f
--- /dev/null
+++ b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/api/MostPopularMoviesService.kt
@@ -0,0 +1,22 @@
+package com.codandotv.streamplayerapp.feature_search.data.api
+
+import com.codandotv.streamplayerapp.core_networking.handleError.NetworkResponse
+import com.codandotv.streamplayerapp.core_networking.handleError.safeRequest
+import com.codandotv.streamplayerapp.feature_search.data.model.ListSearchStreamResponse
+import io.ktor.client.HttpClient
+import io.ktor.client.call.body
+import io.ktor.client.request.get
+import io.ktor.client.request.url
+
+interface MostPopularMoviesService {
+ suspend fun getPopular(): NetworkResponse
+}
+
+class MostPopularMoviesServiceImpl(
+ private val client: HttpClient
+) : MostPopularMoviesService {
+ override suspend fun getPopular(): NetworkResponse =
+ client.safeRequest {
+ url("movie/popular")
+ }
+}
diff --git a/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/api/SearchStreamService.kt b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/api/SearchStreamService.kt
new file mode 100644
index 00000000..1020971f
--- /dev/null
+++ b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/api/SearchStreamService.kt
@@ -0,0 +1,22 @@
+package com.codandotv.streamplayerapp.feature_search.data.api
+
+import com.codandotv.streamplayerapp.core_networking.handleError.NetworkResponse
+import com.codandotv.streamplayerapp.core_networking.handleError.safeRequest
+import com.codandotv.streamplayerapp.feature_search.data.model.ListSearchStreamResponse
+import io.ktor.client.HttpClient
+import io.ktor.client.request.parameter
+import io.ktor.client.request.url
+
+interface SearchStreamService {
+ suspend fun getSearch(query: String): NetworkResponse
+}
+
+class SearchStreamServiceImpl(
+ private val client: HttpClient
+) : SearchStreamService {
+ override suspend fun getSearch(query: String): NetworkResponse =
+ client.safeRequest {
+ url("search/movie")
+ parameter("query", query)
+ }
+}
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/datasource/MostPopularMoviesDataSource.kt b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/datasource/MostPopularMoviesDataSource.kt
similarity index 62%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/datasource/MostPopularMoviesDataSource.kt
rename to feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/datasource/MostPopularMoviesDataSource.kt
index 82f01044..b074864d 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/datasource/MostPopularMoviesDataSource.kt
+++ b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/datasource/MostPopularMoviesDataSource.kt
@@ -1,8 +1,8 @@
-package com.codandotv.streamplayerapp.feature_list_streams.search.data.datasource
+package com.codandotv.streamplayerapp.feature_search.data.datasource
import com.codandotv.streamplayerapp.core_networking.handleError.toFlow
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.model.ListSearchStreamResponse
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.api.MostPopularMoviesService
+import com.codandotv.streamplayerapp.feature_search.data.model.ListSearchStreamResponse
+import com.codandotv.streamplayerapp.feature_search.data.api.MostPopularMoviesService
import kotlinx.coroutines.flow.Flow
interface MostPopularMoviesDataSource {
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/datasource/SearchStreamDataSource.kt b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/datasource/SearchStreamDataSource.kt
similarity index 63%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/datasource/SearchStreamDataSource.kt
rename to feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/datasource/SearchStreamDataSource.kt
index 77f25ce3..e3d65b3b 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/datasource/SearchStreamDataSource.kt
+++ b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/datasource/SearchStreamDataSource.kt
@@ -1,8 +1,8 @@
-package com.codandotv.streamplayerapp.feature_list_streams.search.data.datasource
+package com.codandotv.streamplayerapp.feature_search.data.datasource
import com.codandotv.streamplayerapp.core_networking.handleError.toFlow
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.model.ListSearchStreamResponse
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.api.SearchStreamService
+import com.codandotv.streamplayerapp.feature_search.data.model.ListSearchStreamResponse
+import com.codandotv.streamplayerapp.feature_search.data.api.SearchStreamService
import kotlinx.coroutines.flow.Flow
interface SearchStreamDataSource {
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
new file mode 100644
index 00000000..88fa6d04
--- /dev/null
+++ b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/model/ListSearchStreamResponse.kt
@@ -0,0 +1,22 @@
+package com.codandotv.streamplayerapp.feature_search.data.model
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class ListSearchStreamResponse(
+ @SerialName("results")
+ val results: List
+) {
+ @Serializable
+ data class SearchStreamResponse(
+ @SerialName("id")
+ val id: Int,
+ @SerialName("title")
+ val title: String,
+ @SerialName("overview")
+ val overview: String,
+ @SerialName("poster_path")
+ val posterPath: String? = null
+ )
+}
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/repository/MostPopularMoviesRepository.kt b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/repository/MostPopularMoviesRepository.kt
similarity index 58%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/repository/MostPopularMoviesRepository.kt
rename to feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/repository/MostPopularMoviesRepository.kt
index cbf9ddb3..5fbf97e5 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/repository/MostPopularMoviesRepository.kt
+++ b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/repository/MostPopularMoviesRepository.kt
@@ -1,7 +1,7 @@
-package com.codandotv.streamplayerapp.feature_list_streams.search.data.repository
+package com.codandotv.streamplayerapp.feature_search.data.repository
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.model.ListSearchStreamResponse
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.datasource.MostPopularMoviesDataSource
+import com.codandotv.streamplayerapp.feature_search.data.model.ListSearchStreamResponse
+import com.codandotv.streamplayerapp.feature_search.data.datasource.MostPopularMoviesDataSource
import kotlinx.coroutines.flow.Flow
interface MostPopularMoviesRepository {
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/repository/SearchStreamRepository.kt b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/repository/SearchStreamRepository.kt
similarity index 58%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/repository/SearchStreamRepository.kt
rename to feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/repository/SearchStreamRepository.kt
index d336d2ba..9b101176 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/data/repository/SearchStreamRepository.kt
+++ b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/data/repository/SearchStreamRepository.kt
@@ -1,7 +1,7 @@
-package com.codandotv.streamplayerapp.feature_list_streams.search.data.repository
+package com.codandotv.streamplayerapp.feature_search.data.repository
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.datasource.SearchStreamDataSource
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.model.ListSearchStreamResponse
+import com.codandotv.streamplayerapp.feature_search.data.datasource.SearchStreamDataSource
+import com.codandotv.streamplayerapp.feature_search.data.model.ListSearchStreamResponse
import kotlinx.coroutines.flow.Flow
interface SearchStreamRepository {
diff --git a/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/di/SearchModule.kt b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/di/SearchModule.kt
new file mode 100644
index 00000000..7848bf61
--- /dev/null
+++ b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/di/SearchModule.kt
@@ -0,0 +1,43 @@
+package com.codandotv.streamplayerapp.feature_search.di
+
+import com.codandotv.streamplayerapp.feature_search.data.api.SearchStreamService
+import com.codandotv.streamplayerapp.feature_search.data.datasource.SearchStreamDataSourceImpl
+import com.codandotv.streamplayerapp.feature_search.data.datasource.MostPopularMoviesDataSource
+import com.codandotv.streamplayerapp.feature_search.data.datasource.MostPopularMoviesDataSourceImpl
+import com.codandotv.streamplayerapp.feature_search.data.repository.MostPopularMoviesRepository
+import com.codandotv.streamplayerapp.feature_search.data.repository.MostPopularMoviesRepositoryImpl
+import com.codandotv.streamplayerapp.feature_search.data.api.MostPopularMoviesService
+import com.codandotv.streamplayerapp.feature_search.data.api.MostPopularMoviesServiceImpl
+import com.codandotv.streamplayerapp.feature_search.data.api.SearchStreamServiceImpl
+import com.codandotv.streamplayerapp.feature_search.data.datasource.SearchStreamDataSource
+import com.codandotv.streamplayerapp.feature_search.data.repository.SearchStreamRepository
+import com.codandotv.streamplayerapp.feature_search.data.repository.SearchStreamRepositoryImp
+import com.codandotv.streamplayerapp.feature_search.domain.MostPopularMoviesUseCase
+import com.codandotv.streamplayerapp.feature_search.domain.MostPopularMoviesUseCaseImpl
+import com.codandotv.streamplayerapp.feature_search.domain.SearchUseCase
+import com.codandotv.streamplayerapp.feature_search.domain.SearchUseCaseImpl
+import com.codandotv.streamplayerapp.feature_search.presentation.screens.SearchViewModel
+import org.koin.core.module.dsl.viewModel
+import org.koin.dsl.module
+
+object SearchModule {
+ val module = module {
+ viewModel {
+ SearchViewModel(
+ searchUseCase = get(),
+ mostPopularMoviesUseCase = get()
+ )
+ }
+
+ factory { SearchStreamServiceImpl(get()) }
+ factory { MostPopularMoviesServiceImpl(get()) }
+
+ factory { MostPopularMoviesUseCaseImpl(repository = get()) }
+ factory { MostPopularMoviesDataSourceImpl(service = get()) }
+ factory { MostPopularMoviesRepositoryImpl(dataSource = get()) }
+
+ factory { SearchUseCaseImpl(repository = get()) }
+ factory { SearchStreamDataSourceImpl(service = get()) }
+ factory { SearchStreamRepositoryImp(dataSource = get()) }
+ }
+}
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/domain/MostPopularMoviesUseCase.kt b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/domain/MostPopularMoviesUseCase.kt
similarity index 58%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/domain/MostPopularMoviesUseCase.kt
rename to feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/domain/MostPopularMoviesUseCase.kt
index 1ba461fc..b924c782 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/domain/MostPopularMoviesUseCase.kt
+++ b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/domain/MostPopularMoviesUseCase.kt
@@ -1,7 +1,7 @@
-package com.codandotv.streamplayerapp.feature_list_streams.search.domain
+package com.codandotv.streamplayerapp.feature_search.domain
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.model.ListSearchStreamResponse
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.repository.MostPopularMoviesRepository
+import com.codandotv.streamplayerapp.feature_search.data.model.ListSearchStreamResponse
+import com.codandotv.streamplayerapp.feature_search.data.repository.MostPopularMoviesRepository
import kotlinx.coroutines.flow.Flow
interface MostPopularMoviesUseCase {
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/domain/SearchUseCase.kt b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/domain/SearchUseCase.kt
similarity index 57%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/domain/SearchUseCase.kt
rename to feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/domain/SearchUseCase.kt
index 90e2e3b9..075f7bfe 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/domain/SearchUseCase.kt
+++ b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/domain/SearchUseCase.kt
@@ -1,7 +1,7 @@
-package com.codandotv.streamplayerapp.feature_list_streams.search.domain
+package com.codandotv.streamplayerapp.feature_search.domain
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.model.ListSearchStreamResponse
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.repository.SearchStreamRepository
+import com.codandotv.streamplayerapp.feature_search.data.model.ListSearchStreamResponse
+import com.codandotv.streamplayerapp.feature_search.data.repository.SearchStreamRepository
import kotlinx.coroutines.flow.Flow
interface SearchUseCase {
diff --git a/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/domain/mapper/SearchMapper.kt b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/domain/mapper/SearchMapper.kt
new file mode 100644
index 00000000..a96edcb1
--- /dev/null
+++ b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/domain/mapper/SearchMapper.kt
@@ -0,0 +1,11 @@
+package com.codandotv.streamplayerapp.feature_search.domain.mapper
+
+import com.codandotv.streamplayerapp.core_shared.Url
+import com.codandotv.streamplayerapp.feature_search.data.model.ListSearchStreamResponse.SearchStreamResponse
+import com.codandotv.streamplayerapp.feature_search.presentation.widgets.SearchStreamCardModel
+
+fun SearchStreamResponse.toSearchStreamCardModel() = SearchStreamCardModel(
+ id = id.toString(),
+ title = title,
+ url = "${Url.IMAGE_URL_SIZE_200}${posterPath}"
+)
diff --git a/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/navigation/SearchStreamNavigation.kt b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/navigation/SearchStreamNavigation.kt
new file mode 100644
index 00000000..e8aa897e
--- /dev/null
+++ b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/navigation/SearchStreamNavigation.kt
@@ -0,0 +1,26 @@
+package com.codandotv.streamplayerapp.feature_search.presentation.navigation
+
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.NavHostController
+import androidx.navigation.compose.composable
+import com.codandotv.streamplayerapp.core_navigation.routes.Routes
+import com.codandotv.streamplayerapp.feature_search.di.SearchModule
+import com.codandotv.streamplayerapp.feature_search.presentation.screens.SearchScreen
+import org.koin.compose.module.rememberKoinModules
+import org.koin.core.annotation.KoinExperimentalAPI
+
+@OptIn(KoinExperimentalAPI::class)
+fun NavGraphBuilder.searchStreamsNavGraph(navController: NavHostController) {
+ composable(Routes.SEARCH) { _ ->
+// BackHandler(true) {}
+ rememberKoinModules {
+ listOf(SearchModule.module)
+ }
+ SearchScreen(
+ navController = navController,
+ onNavigateDetailList = { id ->
+ navController.navigate("${Routes.DETAIL}${id}")
+ }
+ )
+ }
+}
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/screens/SearchScreen.kt b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/screens/SearchScreen.kt
similarity index 69%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/screens/SearchScreen.kt
rename to feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/screens/SearchScreen.kt
index f3f68d21..379193e8 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/screens/SearchScreen.kt
+++ b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/screens/SearchScreen.kt
@@ -1,6 +1,5 @@
-package com.codandotv.streamplayerapp.feature_list_streams.search.presentation.screens
+package com.codandotv.streamplayerapp.feature_search.presentation.screens
-import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
@@ -8,48 +7,37 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.CircularProgressIndicator
-import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.platform.LocalLifecycleOwner
-import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavController
import com.codandotv.streamplayerapp.core_navigation.extensions.goBack
-import com.codandotv.streamplayerapp.feature.list.streams.R
-import com.codandotv.streamplayerapp.feature_list_streams.search.domain.mapper.toSearchStreamCardModel
-import com.codandotv.streamplayerapp.feature_list_streams.search.presentation.widgets.SearchStreamCard
-import com.codandotv.streamplayerapp.feature_list_streams.search.presentation.widgets.SearchableTopBar
-import com.codandotv.streamplayerapp.feature_list_streams.search.presentation.widgets.StreamsEmpty
-import com.codandotv.streamplayerapp.feature_list_streams.search.presentation.widgets.StreamsError
-import org.koin.androidx.compose.koinViewModel
+import com.codandotv.streamplayerapp.feature_search.domain.mapper.toSearchStreamCardModel
+import com.codandotv.streamplayerapp.feature_search.presentation.widgets.SearchStreamCard
+import com.codandotv.streamplayerapp.feature_search.presentation.widgets.SearchableTopBar
+import com.codandotv.streamplayerapp.feature_search.presentation.widgets.StreamsEmpty
+import com.codandotv.streamplayerapp.feature_search.presentation.widgets.StreamsError
+import org.jetbrains.compose.resources.stringResource
+import org.koin.compose.viewmodel.koinViewModel
+import streamplayerapp_kmp.feature_search.generated.resources.Res
+import streamplayerapp_kmp.feature_search.generated.resources.search_list_describle
@Composable
fun SearchScreen(
viewModel: SearchViewModel = koinViewModel(),
onNavigateDetailList: (String) -> Unit = {},
navController: NavController,
- disposable: () -> Unit = {}
) {
- val uiState by viewModel.uiState.collectAsStateWithLifecycle()
- Lifecycle(
- lifecycleOwner = LocalLifecycleOwner.current,
- viewModel = viewModel,
- disposable = disposable
- )
-
+ val uiState by viewModel.uiState.collectAsState()
when (uiState) {
is SearchUIState.Success -> {
SetupSearchScreen(
@@ -88,7 +76,6 @@ fun SearchScreen(
}
}
-@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun SetupSearchScreen(
onNavigateDetailList: (String) -> Unit = {},
@@ -129,7 +116,7 @@ private fun SetupSearchScreen(
.verticalScroll(rememberScrollState()),
) {
Text(
- text = stringResource(id = R.string.search_list_describle),
+ text = stringResource(Res.string.search_list_describle),
color = Color.White,
fontWeight = FontWeight.SemiBold,
fontSize = 20.sp,
@@ -150,24 +137,4 @@ private fun SetupSearchScreen(
}
}
}
- BackHandler {
- navController.goBack()
- }
-
-}
-
-@Composable
-private fun Lifecycle(
- lifecycleOwner: LifecycleOwner, viewModel: SearchViewModel, disposable: () -> Unit
-) {
- DisposableEffect(lifecycleOwner) {
- val lifecycle = lifecycleOwner.lifecycle
-
- lifecycle.addObserver(viewModel)
-
- onDispose {
- lifecycle.removeObserver(viewModel)
- disposable.invoke()
- }
- }
-}
+}
\ No newline at end of file
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/screens/SearchUIState.kt b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/screens/SearchUIState.kt
similarity index 58%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/screens/SearchUIState.kt
rename to feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/screens/SearchUIState.kt
index 965ec7dd..3e716dfc 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/screens/SearchUIState.kt
+++ b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/screens/SearchUIState.kt
@@ -1,6 +1,6 @@
-package com.codandotv.streamplayerapp.feature_list_streams.search.presentation.screens
+package com.codandotv.streamplayerapp.feature_search.presentation.screens
-import com.codandotv.streamplayerapp.feature_list_streams.search.data.model.ListSearchStreamResponse
+import com.codandotv.streamplayerapp.feature_search.data.model.ListSearchStreamResponse
sealed class SearchUIState {
data class Success(val listCharacters: ListSearchStreamResponse) : SearchUIState()
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/screens/SearchViewModel.kt b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/screens/SearchViewModel.kt
similarity index 89%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/screens/SearchViewModel.kt
rename to feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/screens/SearchViewModel.kt
index f02c07ac..8a4314b7 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/screens/SearchViewModel.kt
+++ b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/screens/SearchViewModel.kt
@@ -1,11 +1,10 @@
-package com.codandotv.streamplayerapp.feature_list_streams.search.presentation.screens
+package com.codandotv.streamplayerapp.feature_search.presentation.screens
-import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.codandotv.streamplayerapp.core_networking.handleError.catchFailure
-import com.codandotv.streamplayerapp.feature_list_streams.search.domain.MostPopularMoviesUseCase
-import com.codandotv.streamplayerapp.feature_list_streams.search.domain.SearchUseCase
+import com.codandotv.streamplayerapp.feature_search.domain.MostPopularMoviesUseCase
+import com.codandotv.streamplayerapp.feature_search.domain.SearchUseCase
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
@@ -18,7 +17,7 @@ import kotlinx.coroutines.launch
class SearchViewModel(
private val searchUseCase: SearchUseCase,
private val mostPopularMoviesUseCase: MostPopularMoviesUseCase
-) : ViewModel(), DefaultLifecycleObserver {
+) : ViewModel() {
private var tryAgain: () -> Unit = {}
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/widgets/SearchCarousel.kt b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/widgets/SearchCarousel.kt
similarity index 73%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/widgets/SearchCarousel.kt
rename to feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/widgets/SearchCarousel.kt
index 0e884005..d736bac1 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/widgets/SearchCarousel.kt
+++ b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/widgets/SearchCarousel.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp.feature_list_streams.search.presentation.widgets
+package com.codandotv.streamplayerapp.feature_search.presentation.widgets
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@@ -21,21 +21,24 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
-import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.paging.PagingData
-import androidx.paging.compose.collectAsLazyPagingItems
-import androidx.paging.compose.itemContentType
-import androidx.paging.compose.itemKey
-import com.codandotv.streamplayerapp.feature.list.streams.R
-import com.codandotv.streamplayerapp.feature_list_streams.list.presentation.widgets.StreamsCard
-import com.codandotv.streamplayerapp.feature_list_streams.list.presentation.widgets.StreamsCardContent
+import app.cash.paging.compose.collectAsLazyPagingItems
+import app.cash.paging.compose.itemContentType
+import app.cash.paging.compose.itemKey
+import com.codandotv.streamplayerapp.core_shared_ui.widget.StreamsCard
+import com.codandotv.streamplayerapp.core_shared_ui.widget.StreamsCardContent
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.emptyFlow
+import org.jetbrains.compose.resources.stringResource
+import streamplayerapp_kmp.feature_search.generated.resources.Res
+import streamplayerapp_kmp.feature_search.generated.resources.bottom_search_list_error
+import streamplayerapp_kmp.feature_search.generated.resources.empty_search_list
+import streamplayerapp_kmp.feature_search.generated.resources.search_back
+import streamplayerapp_kmp.feature_search.generated.resources.search_list_describle
+import streamplayerapp_kmp.feature_search.generated.resources.search_list_error
data class SearchCarousel(
val genreTitle: String,
@@ -51,7 +54,7 @@ fun SearchCarouselStream(
val lazyPagingItems = content.contentList.collectAsLazyPagingItems()
Text(
- text = stringResource(id = R.string.search_list_describle),
+ text = stringResource(Res.string.search_list_describle),
color = Color.Black,
fontSize = 14.sp
)
@@ -79,17 +82,6 @@ fun SearchCarouselStream(
}
}
-@Composable
-@Preview
-fun StreamsCarouselPreview() {
- SearchCarouselStream(
- content = SearchCarousel(
- genreTitle = "Comédia",
- contentList = emptyFlow()
- )
- )
-}
-
@Composable
fun StreamsError(
onRetry: () -> Unit,
@@ -105,12 +97,12 @@ fun StreamsError(
}) {
Icon(
imageVector = Icons.Filled.Close,
- contentDescription = stringResource(id = R.string.detail_back),
+ contentDescription = stringResource(Res.string.search_back),
tint = Color.White
)
}
Text(
- text = stringResource(id = R.string.search_list_error),
+ text = stringResource(Res.string.search_list_error),
color = Color.White,
fontWeight = FontWeight.SemiBold,
fontSize = 20.sp,
@@ -132,18 +124,17 @@ fun StreamsError(
),
shape = RoundedCornerShape(8.dp),
) {
- Text(text = stringResource(id = R.string.bottom_search_list_error))
+ Text(text = stringResource(Res.string.bottom_search_list_error))
}
}
}
@Composable
-@Preview
fun StreamsEmpty() {
Row(verticalAlignment = Alignment.CenterVertically) {
Column {
Text(
- text = stringResource(id = R.string.empty_search_list),
+ text = stringResource(Res.string.empty_search_list),
color = Color.White,
fontWeight = FontWeight.SemiBold,
fontSize = 20.sp,
@@ -154,12 +145,3 @@ fun StreamsEmpty() {
}
}
}
-
-@Composable
-@Preview
-fun StreamsErrorPreview() {
- StreamsError(
- onRetry = {},
- onCloseButton = {}
- )
-}
\ No newline at end of file
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/widgets/SearchStreamCard.kt b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/widgets/SearchStreamCard.kt
similarity index 82%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/widgets/SearchStreamCard.kt
rename to feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/widgets/SearchStreamCard.kt
index 86d1d674..f496d701 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/widgets/SearchStreamCard.kt
+++ b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/widgets/SearchStreamCard.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp.feature_list_streams.search.presentation.widgets
+package com.codandotv.streamplayerapp.feature_search.presentation.widgets
import androidx.compose.foundation.background
import androidx.compose.foundation.border
@@ -24,8 +24,7 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
-import coil.compose.AsyncImage
-import com.codandotv.streamplayerapp.core_shared_ui.theme.ThemePreviews
+import com.codandotv.streamplayerapp.core_shared_ui.widget.WebImage
@Suppress("MagicNumber")
@Composable
@@ -80,8 +79,8 @@ fun ImageStream(modifier: Modifier, url: String) {
shape = RoundedCornerShape(4.dp),
modifier = modifier
) {
- AsyncImage(
- model = url,
+ WebImage(
+ imageUrl = url,
contentScale = ContentScale.FillBounds,
contentDescription = "",
modifier = Modifier.fillMaxSize()
@@ -107,22 +106,3 @@ fun PlayerIcon(modifier: Modifier) {
)
}
}
-
-@ThemePreviews
-@Composable
-fun SearchStreamCardPreview() {
- SearchStreamCard(
- content = SearchStreamCardModel(
- id = "1",
- title = "The Witcher",
- url = "https://image.tmdb.org/t/p/w200/iwsMu0ehRPbtaSxqiaUDQB9qMWT.jpg"
- ),
- onSearchStreamPressed = {}
- )
-}
-
-@ThemePreviews
-@Composable
-fun PlayerPreview() {
- PlayerIcon(modifier = Modifier)
-}
diff --git a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/widgets/SearchStreams.kt b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/widgets/SearchStreams.kt
similarity index 60%
rename from feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/widgets/SearchStreams.kt
rename to feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/widgets/SearchStreams.kt
index 6626e3ca..01775583 100644
--- a/feature-list-streams/src/main/java/com/codandotv/streamplayerapp/feature_list_streams/search/presentation/widgets/SearchStreams.kt
+++ b/feature-search/src/commonMain/kotlin/com/codandotv/streamplayerapp/feature_search/presentation/widgets/SearchStreams.kt
@@ -1,4 +1,4 @@
-package com.codandotv.streamplayerapp.feature_list_streams.search.presentation.widgets
+package com.codandotv.streamplayerapp.feature_search.presentation.widgets
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
@@ -13,11 +13,7 @@ import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
-import androidx.compose.material.icons.filled.Cast
-import androidx.compose.material.icons.filled.Close
-import androidx.compose.material.icons.filled.MicNone
-import androidx.compose.material.icons.filled.Search
-import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material.icons.filled.Check
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
@@ -28,16 +24,22 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.vector.ImageVector
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.ImeAction
-import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
-import com.codandotv.streamplayerapp.core.shared.ui.R
import com.codandotv.streamplayerapp.core_shared_ui.resources.Colors
-import com.codandotv.streamplayerapp.feature.list.streams.R as ResourceListStream
+import com.codandotv.streamplayerapp.core_shared_ui.widget.CloseButton
+import com.codandotv.streamplayerapp.core_shared_ui.widget.MicButton
+import com.codandotv.streamplayerapp.core_shared_ui.widget.SearchIcon
+import org.jetbrains.compose.resources.painterResource
+import org.jetbrains.compose.resources.stringResource
+import streamplayerapp_kmp.core_shared_ui.generated.resources.icon_back
+import streamplayerapp_kmp.core_shared_ui.generated.resources.icon_cast
+import streamplayerapp_kmp.core_shared_ui.generated.resources.icon_profile
+import streamplayerapp_kmp.core_shared_ui.generated.resources.perfil_fake
+import streamplayerapp_kmp.feature_search.generated.resources.Res
+import streamplayerapp_kmp.feature_search.generated.resources.search_list_main_search
+import streamplayerapp_kmp.core_shared_ui.generated.resources.Res as SharedRes
@Suppress("LongParameterList")
@Composable
@@ -64,7 +66,7 @@ fun SearchableTopBar(
}
@Composable
-private fun StreamPlayerTopBar(
+internal fun StreamPlayerTopBar(
onBackPressed: () -> Unit
) {
Row(
@@ -79,7 +81,7 @@ private fun StreamPlayerTopBar(
) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
- contentDescription = stringResource(id = R.string.icon_back),
+ contentDescription = stringResource(SharedRes.string.icon_back),
tint = Color.White,
)
}
@@ -90,8 +92,8 @@ private fun StreamPlayerTopBar(
onClick = { /* todo */ }
) {
Icon(
- imageVector = Icons.Default.Cast,
- contentDescription = stringResource(id = R.string.icon_cast),
+ imageVector = Icons.Default.Check,
+ contentDescription = stringResource(SharedRes.string.icon_cast),
tint = Color.White,
)
}
@@ -104,15 +106,14 @@ private fun StreamPlayerTopBar(
modifier = Modifier
.height(24.dp)
.clip(RoundedCornerShape(4.dp)),
- painter = painterResource(R.drawable.perfil_fake),
- contentDescription = stringResource(id = R.string.icon_profile),
+ painter = painterResource(SharedRes.drawable.perfil_fake),
+ contentDescription = stringResource(SharedRes.string.icon_profile),
tint = Color.Unspecified,
)
}
}
}
-@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SearchTopBar(
currentSearchText: String,
@@ -142,7 +143,7 @@ fun SearchTopBar(
},
placeholder = {
Text(
- text = stringResource(id = ResourceListStream.string.search_list_main_search),
+ text = stringResource(Res.string.search_list_main_search),
color = Color.Gray
)
},
@@ -167,85 +168,3 @@ fun SearchTopBar(
)
}
}
-
-@Composable
-fun DefaultIcon(
- modifier: Modifier = Modifier,
- searchIcon: ImageVector = Icons.Default.Search,
- iconColor: Color = Color.White,
- contentDescription: String = "",
- onIconClickAction: () -> Unit = {}
-) {
- IconButton(
- modifier = modifier,
- onClick = onIconClickAction
- ) {
- Icon(
- imageVector = searchIcon,
- contentDescription = contentDescription,
- tint = iconColor
- )
- }
-}
-
-@Composable
-fun SearchIcon(action: () -> Unit = {}) {
- DefaultIcon(
- searchIcon = Icons.Filled.Search,
- contentDescription = stringResource(id = R.string.icon_search),
- onIconClickAction = action,
- iconColor = Color.Gray
- )
-}
-
-@Composable
-fun CloseButton(action: () -> Unit = {}) {
- DefaultIcon(
- searchIcon = Icons.Default.Close,
- contentDescription = stringResource(id = R.string.icon_close),
- onIconClickAction = action,
- iconColor = Color.Gray
- )
-}
-
-@Composable
-private fun MicButton(action: () -> Unit = {}) {
- DefaultIcon(
- searchIcon = Icons.Default.MicNone,
- contentDescription = stringResource(id = R.string.icon_mic),
- onIconClickAction = action,
- iconColor = Color.Gray
- )
-}
-
-@Composable
-@Preview
-fun SearchBarPreview() {
- StreamPlayerTopBar(
- onBackPressed = {}
- )
-}
-
-@Composable
-@Preview
-fun SearchTopBarEmptyPreview() {
- SearchTopBar(
- currentSearchText = "",
- onSearchTextChanged = {},
- onSearchDispatched = {},
- onCleanTextPressed = {},
- onSearchIconPressed = {}
- )
-}
-
-@Composable
-@Preview
-fun SearchTopBarPreview() {
- SearchTopBar(
- currentSearchText = "Texto de busca",
- onSearchTextChanged = {},
- onSearchDispatched = {},
- onCleanTextPressed = {},
- onSearchIconPressed = {}
- )
-}
diff --git a/gradle.properties b/gradle.properties
index f63f4eac..1d55b8a4 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -21,5 +21,4 @@ kotlin.code.style=official
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
-android.defaults.buildfeatures.buildconfig=true
android.nonFinalResIds=false
\ No newline at end of file
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 865020d6..11cd12dd 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,55 +1,34 @@
[versions]
-kotlin = "1.9.25"
-android_gradle_plugin = "8.2.2"
-koin = "3.4.0"
-koin-annotations-bom = "1.3.0"
-ksp = "1.9.25-1.0.20"
+kotlin = "2.1.10"
+android_gradle_plugin = "8.7.2"
+koin = "4.0.1"
+ksp = "2.1.10-1.0.29"
+
dokka = "1.9.10"
kover = "0.7.5"
detekt = "1.23.6"
+compose_plugin_multiplataform = "1.7.3"
+navigation-compose-version = "2.7.0-alpha07"
+paging-compose = "3.3.0-alpha02-0.5.1"
+buildkonfig = "0.15.2"
#Test
test_junit = "4.13.2"
androidx_core_testing = "2.2.0"
mockk = "1.13.7"
-kotlinx-coroutines-test= "1.8.1"
-
-#Android Test
-androidx_test_core = "1.6.1"
-androidx_test_rules = "1.6.1"
-androidx_test_runner = "1.6.2"
-androidx_test_junit_ext = "1.2.1"
-mockWebServer = "4.10.0"
-
-#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"
+kotlinx-coroutines-test = "1.8.1"
#Networking
-moshi = "1.14.0"
okhttp = "4.12.0"
-retrofit = "2.9.0"
-
-#Compose
-compose = "1.5.15"
-compose_bom = "2024.09.02"
-compose_material_3 = "1.3.0"
-compose_activity = "1.5.0"
-compose_icons = "1.4.3"
-compose_navigation = "2.8.1"
-lifecycle_version = "2.8.6"
-compose_pagging="3.3.2"
-
-coil = "2.3.0"
+ktor = "3.0.1"
+
+coil = "3.1.0"
lottie = "5.2.0"
#Room Database
-room = "2.5.2"
+room = "2.7.0-alpha13"
+sqlite = "2.5.0-SNAPSHOT"
+
android_youtube_player_version = "12.0.0"
@@ -57,104 +36,71 @@ android_youtube_player_version = "12.0.0"
kotlin_gradle_plugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
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" }
+coil = { group = "io.coil-kt.coil3", name = "coil-compose", version.ref = "coil" }
+coil-network-ktor3 = { module = "io.coil-kt.coil3:coil-network-ktor3", 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" }
-
-# AndroidX Lifecycle
-androidx_viewmodel_lifecycle-extensions = { group = "androidx.lifecycle", name = "lifecycle-extensions", version.ref = "viewmodel" }
-androidx_common_java = { group = "androidx.lifecycle", name = "lifecycle-reactivestreams", version.ref = "viewmodel" }
-
-# AndroidX test
-androidx_test_core = { group = "androidx.test", name = "core-ktx", version.ref = "androidx_test_core" }
-androidx_test_rules = { group = "androidx.test", name = "rules", version.ref = "androidx_test_rules" }
-androidx_test_runner = { group = "androidx.test", name = "runner", version.ref = "androidx_test_runner" }
-androidx_test_junit_ext = { group = "androidx.test.ext", name = "junit-ktx", version.ref = "androidx_test_junit_ext" }
-android_test_mockwebserver = { group = "com.squareup.okhttp3", name = "mockwebserver", version.ref = "mockWebServer" }
-
-# Google
-google_material = { group = "com.google.android.material", name = "material", version.ref = "material" }
-
-# Compose
-compose_bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose_bom" }
-compose_ui = { module = "androidx.compose.ui:ui" }
-compose_toolingpreview = { module = "androidx.compose.ui:ui-tooling-preview" }
-compose_icons = { module = "androidx.compose.material:material-icons-extended" }
-compose_lifecycle = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "lifecycle_version" }
-compose_material3 = { group = "androidx.compose.material3", name = "material3", version.ref = "compose_material_3" }
-compose_navigation = { group = "androidx.navigation", name = "navigation-compose", version.ref = "compose_navigation" }
-compose_pagging = { group = "androidx.paging", name = "paging-compose", version.ref = "compose_pagging" }
-compose_activity = { module = "androidx.activity:activity-compose" }
-compose_ui_tooling = { module = "androidx.compose.ui:ui-tooling" }
-compose_ui_test = { module = "androidx.compose.ui:ui-test-junit4" }
-compose_manifest = { module = "androidx.compose.ui:ui-test-manifest" }
-compose_uitest = { module = "androidx.compose.ui:ui-test" }
-compose_junit4 = { module = "androidx.compose.ui:ui-test-junit4" }
+navigation-compose = { module = "org.jetbrains.androidx.navigation:navigation-compose", version.ref = "navigation-compose-version" }
+paging-compose = { module = "app.cash.paging:paging-compose-common", version.ref = "paging-compose" }
# 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_annotations = { group = "io.insert-koin", name = "koin-annotations", version.ref = "koin-annotations-bom" }
-koin_compiler = { group = "io.insert-koin", name = "koin-ksp-compiler", version.ref = "koin-annotations-bom" }
-koin_compose = { group = "io.insert-koin", name = "koin-androidx-compose", version.ref = "koin" }
+koin_core = { group = "io.insert-koin", name = "koin-core", 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" }
#Networking
-retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
-moshi = { group = "com.squareup.moshi", name = "moshi-kotlin", version.ref = "moshi" }
-moshi_converter = { group = "com.squareup.retrofit2", name = "converter-moshi", version.ref = "retrofit" }
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }
interceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" }
-compose-material = { group = "androidx.wear.compose", name = "compose-material", version = "1.2.0" }
+
+ktor_client_core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
+ktor_client_okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" }
+ktor_client_logger = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" }
+ktor_client_auth = { module = "io.ktor:ktor-client-auth", version.ref = "ktor" }
+ktor_client_darwin = { group = "io.ktor", name = "ktor-client-darwin", version.ref = "ktor" }
+ktor_client_content_negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" }
+ktor_client_content_serialization_json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" }
#Room
-roomRuntime = { group = "androidx.room", name = "room-runtime", version.ref = "room"}
-roomCompiler = { group = "androidx.room", name= "room-compiler", version.ref = "room"}
-roomKtx = { group = "androidx.room", name = "room-ktx", version.ref = "room"}
+room_runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" }
+room_compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
+room_bundled = { group = "androidx.sqlite", name = "sqlite-bundled", version.ref = "sqlite" }
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" }
[bundles]
-room = ["roomRuntime","roomKtx"]
-compose = ["compose.ui", "compose.icons", "compose.material3","compose_pagging", "compose.lifecycle", "compose.navigation", "compose.activity", "compose.ui.tooling"]
-composetest = ["compose.uitest", "compose.junit4", "compose.manifest", "compose.ui.test"]
-networking = ["retrofit", "moshi", "moshi_converter", "okhttp", "interceptor"]
-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"]
+test = ["junit", "mockk", "mockk_android", "viewmodel_test", "koin_test", "coroutines_test"]
[plugins]
android_application = { id = "com.android.application", version.ref = "android_gradle_plugin" }
android_library = { id = "com.android.library", version.ref = "android_gradle_plugin" }
kotlin_android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
-kotlin_kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" }
-kotlin_parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" }
-ksp = { id = "com.google.devtools.ksp", version.ref = "ksp"}
-dokka = { id = "org.jetbrains.dokka", version.ref = "dokka"}
+serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
+
+jetbrains-compose = { id = "org.jetbrains.compose", version.ref = "compose_plugin_multiplataform" }
+kotlin_multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
+compose_compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
+room = { id = "androidx.room", version.ref = "room" }
+
+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
+buildkonfig_plugin = { id = "com.codingfeline.buildkonfig", version.ref = "buildkonfig" }
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index e708b1c0..2c352119 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 30be1904..960f6e70 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,8 @@
-#Sat Apr 08 14:40:45 BRT 2023
+#Wed Feb 19 11:41:18 BRT 2025
distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
distributionPath=wrapper/dists
-zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index 4f906e0c..f5feea6d 100755
--- a/gradlew
+++ b/gradlew
@@ -1,7 +1,7 @@
-#!/usr/bin/env sh
+#!/bin/sh
#
-# Copyright 2015 the original author or authors.
+# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,69 +15,104 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
+# SPDX-License-Identifier: Apache-2.0
+#
##############################################################################
-##
-## Gradle start up script for UN*X
-##
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
##############################################################################
# Attempt to set APP_HOME
+
# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
+' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
+MAX_FD=maximum
warn () {
echo "$*"
-}
+} >&2
die () {
echo
echo "$*"
echo
exit 1
-}
+} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
- NONSTOP* )
- nonstop=true
- ;;
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -87,9 +122,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
+ JAVACMD=$JAVA_HOME/jre/sh/java
else
- JAVACMD="$JAVA_HOME/bin/java"
+ JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -98,88 +133,120 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
- JAVACMD="java"
- which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+ JAVACMD=java
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
+ fi
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
fi
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# For Cygwin or MSYS, switch paths to Windows format before running java
-if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-
- JAVACMD=`cygpath --unix "$JAVACMD"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
# Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
fi
- i=`expr $i + 1`
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
done
- case $i in
- 0) set -- ;;
- 1) set -- "$args0" ;;
- 2) set -- "$args0" "$args1" ;;
- 3) set -- "$args0" "$args1" "$args2" ;;
- 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
- esac
fi
-# Escape application args
-save () {
- for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
- echo " "
-}
-APP_ARGS=`save "$@"`
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
index 107acd32..9d21a218 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -13,8 +13,10 @@
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
+@rem SPDX-License-Identifier: Apache-2.0
+@rem
-@if "%DEBUG%" == "" @echo off
+@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,7 +27,8 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -40,13 +43,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto execute
+if %ERRORLEVEL% equ 0 goto execute
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
goto fail
@@ -56,11 +59,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
+echo. 1>&2
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
goto fail
@@ -75,13 +78,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end
@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
+if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal
diff --git a/iosApp/Configuration/Config.xcconfig b/iosApp/Configuration/Config.xcconfig
new file mode 100644
index 00000000..81c20de5
--- /dev/null
+++ b/iosApp/Configuration/Config.xcconfig
@@ -0,0 +1,3 @@
+TEAM_ID=
+BUNDLE_ID=com.codandotv.streamplayerapp.KotlinProject
+APP_NAME=KotlinProject
\ No newline at end of file
diff --git a/iosApp/iosApp.xcodeproj/project.pbxproj b/iosApp/iosApp.xcodeproj/project.pbxproj
new file mode 100644
index 00000000..25552509
--- /dev/null
+++ b/iosApp/iosApp.xcodeproj/project.pbxproj
@@ -0,0 +1,422 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 56;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557BA273AAA24004C7B11 /* Assets.xcassets */; };
+ 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */; };
+ 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* iOSApp.swift */; };
+ 5BAD97872D7CCDDA00D93987 /* Lottie.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BAD97862D7CCDDA00D93987 /* Lottie.swift */; };
+ 5BAD97892D7CCEA700D93987 /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = 5BAD97882D7CCEA700D93987 /* Lottie */; };
+ 7555FF83242A565900829871 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF82242A565900829871 /* ContentView.swift */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 058557BA273AAA24004C7B11 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
+ 2152FB032600AC8F00CF470E /* iOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSApp.swift; sourceTree = ""; };
+ 5BAD97862D7CCDDA00D93987 /* Lottie.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Lottie.swift; sourceTree = ""; };
+ 7555FF7B242A565900829871 /* KotlinProject.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KotlinProject.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 7555FF82242A565900829871 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
+ 7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ AB3632DC29227652001CCB65 /* Config.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ B92378962B6B1156000C7307 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5BAD97892D7CCEA700D93987 /* Lottie in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 058557D7273AAEEB004C7B11 /* Preview Content */ = {
+ isa = PBXGroup;
+ children = (
+ 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */,
+ );
+ path = "Preview Content";
+ sourceTree = "";
+ };
+ 42799AB246E5F90AF97AA0EF /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+ 7555FF72242A565900829871 = {
+ isa = PBXGroup;
+ children = (
+ AB1DB47929225F7C00F7AF9C /* Configuration */,
+ 7555FF7D242A565900829871 /* iosApp */,
+ 7555FF7C242A565900829871 /* Products */,
+ 42799AB246E5F90AF97AA0EF /* Frameworks */,
+ );
+ sourceTree = "";
+ };
+ 7555FF7C242A565900829871 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 7555FF7B242A565900829871 /* KotlinProject.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 7555FF7D242A565900829871 /* iosApp */ = {
+ isa = PBXGroup;
+ children = (
+ 5BAD97862D7CCDDA00D93987 /* Lottie.swift */,
+ 058557BA273AAA24004C7B11 /* Assets.xcassets */,
+ 7555FF82242A565900829871 /* ContentView.swift */,
+ 7555FF8C242A565B00829871 /* Info.plist */,
+ 2152FB032600AC8F00CF470E /* iOSApp.swift */,
+ 058557D7273AAEEB004C7B11 /* Preview Content */,
+ );
+ path = iosApp;
+ sourceTree = "";
+ };
+ AB1DB47929225F7C00F7AF9C /* Configuration */ = {
+ isa = PBXGroup;
+ children = (
+ AB3632DC29227652001CCB65 /* Config.xcconfig */,
+ );
+ path = Configuration;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 7555FF7A242A565900829871 /* iosApp */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */;
+ buildPhases = (
+ F36B1CEB2AD83DDC00CB74D5 /* Compile Kotlin Framework */,
+ 7555FF77242A565900829871 /* Sources */,
+ B92378962B6B1156000C7307 /* Frameworks */,
+ 7555FF79242A565900829871 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = iosApp;
+ packageProductDependencies = (
+ 5BAD97882D7CCEA700D93987 /* Lottie */,
+ );
+ productName = iosApp;
+ productReference = 7555FF7B242A565900829871 /* KotlinProject.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 7555FF73242A565900829871 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = YES;
+ LastSwiftUpdateCheck = 1130;
+ LastUpgradeCheck = 1540;
+ ORGANIZATIONNAME = orgName;
+ TargetAttributes = {
+ 7555FF7A242A565900829871 = {
+ CreatedOnToolsVersion = 11.3.1;
+ };
+ };
+ };
+ buildConfigurationList = 7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */;
+ compatibilityVersion = "Xcode 14.0";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 7555FF72242A565900829871;
+ packageReferences = (
+ 5BAD97852D7CCDB400D93987 /* XCRemoteSwiftPackageReference "lottie-spm" */,
+ );
+ productRefGroup = 7555FF7C242A565900829871 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 7555FF7A242A565900829871 /* iosApp */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 7555FF79242A565900829871 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */,
+ 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ F36B1CEB2AD83DDC00CB74D5 /* Compile Kotlin Framework */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ );
+ name = "Compile Kotlin Framework";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "if [ \"YES\" = \"$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED\" ]; then\n echo \"Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \\\"YES\\\"\"\n exit 0\nfi\ncd \"$SRCROOT/..\"\n./gradlew :composeApp:embedAndSignAppleFrameworkForXcode\n";
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 7555FF77242A565900829871 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */,
+ 7555FF83242A565900829871 /* ContentView.swift in Sources */,
+ 5BAD97872D7CCDDA00D93987 /* Lottie.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 7555FFA3242A565B00829871 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 15.3;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ };
+ name = Debug;
+ };
+ 7555FFA4242A565B00829871 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 15.3;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 7555FFA6242A565B00829871 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\"";
+ DEVELOPMENT_TEAM = "${TEAM_ID}";
+ ENABLE_PREVIEWS = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\n$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)",
+ );
+ INFOPLIST_FILE = iosApp/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 15.3;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}";
+ PRODUCT_NAME = "${APP_NAME}";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 7555FFA7242A565B00829871 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
+ DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\"";
+ DEVELOPMENT_TEAM = "${TEAM_ID}";
+ ENABLE_PREVIEWS = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\n$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)",
+ );
+ INFOPLIST_FILE = iosApp/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 15.3;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}";
+ PRODUCT_NAME = "${APP_NAME}";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 7555FFA3242A565B00829871 /* Debug */,
+ 7555FFA4242A565B00829871 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 7555FFA6242A565B00829871 /* Debug */,
+ 7555FFA7242A565B00829871 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+
+/* Begin XCRemoteSwiftPackageReference section */
+ 5BAD97852D7CCDB400D93987 /* XCRemoteSwiftPackageReference "lottie-spm" */ = {
+ isa = XCRemoteSwiftPackageReference;
+ repositoryURL = "https://github.com/airbnb/lottie-spm.git";
+ requirement = {
+ kind = upToNextMajorVersion;
+ minimumVersion = 4.5.1;
+ };
+ };
+/* End XCRemoteSwiftPackageReference section */
+
+/* Begin XCSwiftPackageProductDependency section */
+ 5BAD97882D7CCEA700D93987 /* Lottie */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = 5BAD97852D7CCDB400D93987 /* XCRemoteSwiftPackageReference "lottie-spm" */;
+ productName = Lottie;
+ };
+/* End XCSwiftPackageProductDependency section */
+ };
+ rootObject = 7555FF73242A565900829871 /* Project object */;
+}
diff --git a/iosApp/iosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/iosApp/iosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000..919434a6
--- /dev/null
+++ b/iosApp/iosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 00000000..18d98100
--- /dev/null
+++ b/iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/iosApp/iosApp.xcodeproj/project.xcworkspace/xcuserdata/pedroalvarez.xcuserdatad/UserInterfaceState.xcuserstate b/iosApp/iosApp.xcodeproj/project.xcworkspace/xcuserdata/pedroalvarez.xcuserdatad/UserInterfaceState.xcuserstate
new file mode 100644
index 00000000..82332d93
Binary files /dev/null and b/iosApp/iosApp.xcodeproj/project.xcworkspace/xcuserdata/pedroalvarez.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/iosApp/iosApp.xcodeproj/xcuserdata/pedroalvarez.xcuserdatad/xcschemes/xcschememanagement.plist b/iosApp/iosApp.xcodeproj/xcuserdata/pedroalvarez.xcuserdatad/xcschemes/xcschememanagement.plist
new file mode 100644
index 00000000..56b5955f
--- /dev/null
+++ b/iosApp/iosApp.xcodeproj/xcuserdata/pedroalvarez.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -0,0 +1,14 @@
+
+
+
+
+ SchemeUserState
+
+ iosApp.xcscheme_^#shared#^_
+
+ orderHint
+ 0
+
+
+
+
diff --git a/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json b/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json
new file mode 100644
index 00000000..ee7e3ca0
--- /dev/null
+++ b/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "colors" : [
+ {
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
\ No newline at end of file
diff --git a/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 00000000..8edf56e7
--- /dev/null
+++ b/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,14 @@
+{
+ "images" : [
+ {
+ "filename" : "app-icon-1024.png",
+ "idiom" : "universal",
+ "platform" : "ios",
+ "size" : "1024x1024"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png b/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png
new file mode 100644
index 00000000..53fc536f
Binary files /dev/null and b/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png differ
diff --git a/iosApp/iosApp/Assets.xcassets/Contents.json b/iosApp/iosApp/Assets.xcassets/Contents.json
new file mode 100644
index 00000000..4aa7c535
--- /dev/null
+++ b/iosApp/iosApp/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
\ No newline at end of file
diff --git a/iosApp/iosApp/ContentView.swift b/iosApp/iosApp/ContentView.swift
new file mode 100644
index 00000000..fad7f5d8
--- /dev/null
+++ b/iosApp/iosApp/ContentView.swift
@@ -0,0 +1,21 @@
+import UIKit
+import SwiftUI
+import streamplayerapp
+
+struct ComposeView: UIViewControllerRepresentable {
+ func makeUIViewController(context: Context) -> UIViewController {
+ MainViewControllerKt.MainViewController()
+ }
+
+ func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
+}
+
+struct ContentView: View {
+ var body: some View {
+ ComposeView()
+ .ignoresSafeArea(.keyboard) // Compose has own keyboard handler
+ }
+}
+
+
+
diff --git a/iosApp/iosApp/Info.plist b/iosApp/iosApp/Info.plist
new file mode 100644
index 00000000..412e3781
--- /dev/null
+++ b/iosApp/iosApp/Info.plist
@@ -0,0 +1,50 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ $(PRODUCT_BUNDLE_PACKAGE_TYPE)
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1
+ LSRequiresIPhoneOS
+
+ CADisableMinimumFrameDurationOnPhone
+
+ UIApplicationSceneManifest
+
+ UIApplicationSupportsMultipleScenes
+
+
+ UILaunchScreen
+
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
diff --git a/iosApp/iosApp/Lottie.swift b/iosApp/iosApp/Lottie.swift
new file mode 100644
index 00000000..dbd28a6f
--- /dev/null
+++ b/iosApp/iosApp/Lottie.swift
@@ -0,0 +1,60 @@
+import Lottie
+import UIKit
+import streamplayerapp
+
+class LottieViewProviderImpl : LottieViewProvider {
+ func provideLottieView(lottieAnimationJson: String,onAnimationFinish: @escaping () -> Void) -> UIView {
+ let lottieView = LottieView()
+ lottieView.setupLottieAnimationView(
+ animationContentJson: lottieAnimationJson,
+ onAnimationFinished: onAnimationFinish
+ )
+ return lottieView
+ }
+}
+class LottieView : UIView {
+
+ private let animationView: LottieAnimationView
+ var onAnimationFinished: (() -> Void)?
+
+ override init(frame: CGRect) {
+ animationView = LottieAnimationView()
+ super.init(frame: frame)
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented.")
+ }
+
+ func setupLottieAnimationView(animationContentJson: String, onAnimationFinished: @escaping () -> Void) {
+ self.onAnimationFinished = onAnimationFinished
+
+ animationView.contentMode = .scaleAspectFit
+ addSubview(animationView)
+
+ animationView.translatesAutoresizingMaskIntoConstraints = false
+ NSLayoutConstraint.activate([
+ animationView.leftAnchor.constraint(equalTo: leftAnchor),
+ animationView.rightAnchor.constraint(equalTo: rightAnchor),
+ animationView.topAnchor.constraint(equalTo: topAnchor),
+ animationView.bottomAnchor.constraint(equalTo: bottomAnchor)
+ ])
+
+ animationView.loopMode = .playOnce // Toca apenas uma vez
+ animationView.frame = bounds
+
+ if let animation = loadLottieAnimation(from: animationContentJson) {
+ animationView.animation = animation
+ animationView.play { finished in
+ if finished {
+ self.onAnimationFinished?() // Chama o callback quando terminar
+ }
+ }
+ }
+ }
+
+ func loadLottieAnimation(from jsonString: String) -> LottieAnimation? {
+ guard let data = jsonString.data(using: .utf8) else { return nil }
+ return try? JSONDecoder().decode(LottieAnimation.self, from: data)
+ }
+}
diff --git a/iosApp/iosApp/Lottie/Lottie.swift b/iosApp/iosApp/Lottie/Lottie.swift
new file mode 100644
index 00000000..4f0144d0
--- /dev/null
+++ b/iosApp/iosApp/Lottie/Lottie.swift
@@ -0,0 +1,56 @@
+import Lottie
+import UIKit
+import streamplayerapp
+
+class LottieViewProviderImpl : LottieViewProvider {
+ func provideLottieView(lottieAnimationJson: String) -> UIView {
+ let lottieView = LottieView()
+ lottieView.setupLottieAnimationView(
+ animationContentJson: lottieAnimationJson
+ )
+ return lottieView
+ }
+}
+
+class LottieView : UIView {
+
+ private let animationView: LottieAnimationView
+
+ override init(frame: CGRect) {
+ animationView = LottieAnimationView()
+
+ super.init(frame: frame)
+ }
+
+ required init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented.")
+ }
+
+ func setupLottieAnimationView(animationContentJson: String) {
+
+ animationView.contentMode = .scaleAspectFit
+
+ addSubview(animationView)
+
+ animationView.translatesAutoresizingMaskIntoConstraints = false
+
+ animationView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
+ animationView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
+ animationView.topAnchor.constraint(equalTo: topAnchor).isActive = true
+ animationView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
+
+ animationView.loopMode = .loop
+ animationView.frame = bounds
+
+ if let animation = loadLottieAnimation(from: animationContentJson) {
+ animationView.animation = animation
+ animationView.loopMode = .loop
+ animationView.play()
+ }
+ }
+
+ func loadLottieAnimation(from jsonString: String) -> LottieAnimation? {
+ guard let data = jsonString.data(using: .utf8) else { return nil }
+ return try? JSONDecoder().decode(LottieAnimation.self, from: data)
+ }
+}
diff --git a/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json b/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json
new file mode 100644
index 00000000..4aa7c535
--- /dev/null
+++ b/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
\ No newline at end of file
diff --git a/iosApp/iosApp/iOSApp.swift b/iosApp/iosApp/iOSApp.swift
new file mode 100644
index 00000000..dec7c719
--- /dev/null
+++ b/iosApp/iosApp/iOSApp.swift
@@ -0,0 +1,16 @@
+import SwiftUI
+import streamplayerapp
+
+@main
+struct iOSApp: App {
+
+ init() {
+ KoinIosHelper().doInitKoin(lottieViewProvider: LottieViewProviderImpl())
+ }
+
+ var body: some Scene {
+ WindowGroup {
+ ContentView()
+ }
+ }
+}
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 2e3a17f0..7bbc2720 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,4 +1,5 @@
-@file:Suppress("UnstableApiUsage")
+rootProject.name = "StreamPlayerApp-KMP"
+
pluginManagement {
includeBuild("build-logic")
repositories {
@@ -14,11 +15,12 @@ dependencyResolutionManagement {
mavenCentral()
maven { setUrl("https://jitpack.io") }
maven(url = uri("https://oss.sonatype.org/content/repositories/snapshots/"))
+
}
}
-include(":app")
+include(":composeApp")
include(":feature-list-streams")
include(":core-shared")
include(":core-networking")
@@ -26,6 +28,8 @@ include(":core-shared-ui")
include(":core-navigation")
include(":feature-profile")
include(":core-local-storage")
-include(":feature-favorites")
+include(":feature-detail")
+include(":feature-search")
+
-enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
\ No newline at end of file
+enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")