diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 547dcab258..4b2b4bcb03 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -155,6 +155,8 @@ dependencies { implementation(projects.features.onramp.impl) implementation(projects.features.onboardingV2.api) implementation(projects.features.onboardingV2.impl) + implementation(projects.features.stories.api) + implementation(projects.features.stories.impl) /** AndroidX libraries */ implementation(deps.androidx.core.ktx) diff --git a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt index b505280f91..2b88040fa9 100644 --- a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt +++ b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt @@ -16,6 +16,7 @@ import com.tangem.features.onramp.component.* import com.tangem.features.pushnotifications.api.navigation.PushNotificationsRouter import com.tangem.features.send.api.navigation.SendRouter import com.tangem.features.staking.api.navigation.StakingRouter +import com.tangem.features.stories.api.component.StoriesComponent import com.tangem.features.tester.api.TesterRouter import com.tangem.features.tokendetails.navigation.TokenDetailsRouter import com.tangem.features.wallet.navigation.WalletRouter @@ -57,6 +58,7 @@ internal class ChildFactory @Inject constructor( private val swapSelectTokensComponentFactory: SwapSelectTokensComponent.Factory, private val onboardingEntryComponentFactory: OnboardingEntryComponent.Factory, private val welcomeComponentFactory: WelcomeComponent.Factory, + private val storiesComponentFactory: StoriesComponent.Factory, private val sendRouter: SendRouter, private val tokenDetailsRouter: TokenDetailsRouter, private val walletRouter: WalletRouter, @@ -200,6 +202,13 @@ internal class ChildFactory @Inject constructor( componentFactory = onboardingEntryComponentFactory, ) } + is AppRoute.Stories -> { + createComponentChild( + contextProvider = contextProvider(route, contextFactory), + params = StoriesComponent.Params, + componentFactory = storiesComponentFactory, + ) + } is AppRoute.AccessCodeRecovery, is AppRoute.AppCurrencySelector, is AppRoute.ModalNotification, @@ -412,6 +421,13 @@ internal class ChildFactory @Inject constructor( componentFactory = onboardingEntryComponentFactory, ) } + is AppRoute.Stories -> { + route.asComponentChild( + contextProvider = contextProvider(route, contextFactory), + params = StoriesComponent.Params, + componentFactory = storiesComponentFactory, + ) + } } // endregion } diff --git a/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt b/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt index e17b766993..2c35ef7feb 100644 --- a/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt +++ b/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt @@ -339,4 +339,7 @@ sealed class AppRoute(val path: String) : Route { AddBackup, // continue backup process for existing wallet 1 } } + + @Serializable + data object Stories : AppRoute(path = "/stories") } diff --git a/core/config-toggles/src/main/assets/configs/feature_toggles_config.json b/core/config-toggles/src/main/assets/configs/feature_toggles_config.json index 60580e40b7..5cdea44710 100644 --- a/core/config-toggles/src/main/assets/configs/feature_toggles_config.json +++ b/core/config-toggles/src/main/assets/configs/feature_toggles_config.json @@ -26,5 +26,9 @@ { "name": "NAVIGATION_REFACTORING", "version": "undefined" + }, + { + "name": "STORIES_ENABLED", + "version": "undefined" } ] diff --git a/features/stories/api/.gitignore b/features/stories/api/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/features/stories/api/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/features/stories/api/build.gradle.kts b/features/stories/api/build.gradle.kts new file mode 100644 index 0000000000..625619ce97 --- /dev/null +++ b/features/stories/api/build.gradle.kts @@ -0,0 +1,16 @@ +plugins { + alias(deps.plugins.android.library) + alias(deps.plugins.kotlin.android) + id("kotlin-parcelize") + id("configuration") +} + +android { + namespace = "com.tangem.features.stories.api" +} + +dependencies { + /* Project - Core */ + implementation(projects.core.decompose) + implementation(projects.core.ui) +} \ No newline at end of file diff --git a/features/stories/api/src/main/java/com/tangem/features/stories/api/StoriesFeatureToggles.kt b/features/stories/api/src/main/java/com/tangem/features/stories/api/StoriesFeatureToggles.kt new file mode 100644 index 0000000000..9ca79e0a2c --- /dev/null +++ b/features/stories/api/src/main/java/com/tangem/features/stories/api/StoriesFeatureToggles.kt @@ -0,0 +1,6 @@ +package com.tangem.features.stories.api + +interface StoriesFeatureToggles { + + val isFeatureEnabled: Boolean +} diff --git a/features/stories/api/src/main/java/com/tangem/features/stories/api/component/StoriesComponent.kt b/features/stories/api/src/main/java/com/tangem/features/stories/api/component/StoriesComponent.kt new file mode 100644 index 0000000000..c0ddca68ca --- /dev/null +++ b/features/stories/api/src/main/java/com/tangem/features/stories/api/component/StoriesComponent.kt @@ -0,0 +1,13 @@ +package com.tangem.features.stories.api.component + +import com.tangem.core.decompose.factory.ComponentFactory +import com.tangem.core.ui.decompose.ComposableContentComponent + +interface StoriesComponent : ComposableContentComponent { + interface Factory : ComponentFactory + + /** + * Params + */ + data object Params +} diff --git a/features/stories/impl/.gitignore b/features/stories/impl/.gitignore new file mode 100644 index 0000000000..42afabfd2a --- /dev/null +++ b/features/stories/impl/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/features/stories/impl/build.gradle.kts b/features/stories/impl/build.gradle.kts new file mode 100644 index 0000000000..2e9bd447e7 --- /dev/null +++ b/features/stories/impl/build.gradle.kts @@ -0,0 +1,28 @@ +plugins { + alias(deps.plugins.android.library) + alias(deps.plugins.kotlin.android) + alias(deps.plugins.kotlin.kapt) + alias(deps.plugins.hilt.android) + id("configuration") +} + +android { + namespace = "com.tangem.features.stories.impl" +} + +dependencies { + + implementation(deps.compose.ui) + implementation(deps.compose.material3) + + implementation(projects.core.configToggles) + implementation(projects.core.decompose) + implementation(projects.core.ui) + + /** Feature modules */ + implementation(projects.features.stories.api) + + /** DI */ + implementation(deps.hilt.android) + kapt(deps.hilt.kapt) +} \ No newline at end of file diff --git a/features/stories/impl/src/main/java/com/tangem/features/stories/impl/DefaultStoriesComponent.kt b/features/stories/impl/src/main/java/com/tangem/features/stories/impl/DefaultStoriesComponent.kt new file mode 100644 index 0000000000..fa7bf74878 --- /dev/null +++ b/features/stories/impl/src/main/java/com/tangem/features/stories/impl/DefaultStoriesComponent.kt @@ -0,0 +1,28 @@ +package com.tangem.features.stories.impl + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.tangem.core.decompose.context.AppComponentContext +import com.tangem.features.stories.api.component.StoriesComponent +import com.tangem.features.stories.impl.ui.StoriesComponentContent +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject + +// todo Temporary remove in AND-9353 +@Suppress("UnusedPrivateMember") +internal class DefaultStoriesComponent @AssistedInject constructor( + @Assisted appComponentContext: AppComponentContext, + @Assisted params: StoriesComponent.Params, +) : StoriesComponent, AppComponentContext by appComponentContext { + + @Composable + override fun Content(modifier: Modifier) { + StoriesComponentContent() + } + + @AssistedFactory + interface Factory : StoriesComponent.Factory { + override fun create(context: AppComponentContext, params: StoriesComponent.Params): DefaultStoriesComponent + } +} diff --git a/features/stories/impl/src/main/java/com/tangem/features/stories/impl/DefaultStoriesFeatureToggles.kt b/features/stories/impl/src/main/java/com/tangem/features/stories/impl/DefaultStoriesFeatureToggles.kt new file mode 100644 index 0000000000..726eef5ac1 --- /dev/null +++ b/features/stories/impl/src/main/java/com/tangem/features/stories/impl/DefaultStoriesFeatureToggles.kt @@ -0,0 +1,11 @@ +package com.tangem.features.stories.impl + +import com.tangem.core.configtoggle.feature.FeatureTogglesManager +import com.tangem.features.stories.api.StoriesFeatureToggles + +internal class DefaultStoriesFeatureToggles( + private val featureTogglesManager: FeatureTogglesManager, +) : StoriesFeatureToggles { + override val isFeatureEnabled: Boolean + get() = featureTogglesManager.isFeatureEnabled("STORIES_ENABLED") +} diff --git a/features/stories/impl/src/main/java/com/tangem/features/stories/impl/di/StoriesComponentModule.kt b/features/stories/impl/src/main/java/com/tangem/features/stories/impl/di/StoriesComponentModule.kt new file mode 100644 index 0000000000..760804fb1d --- /dev/null +++ b/features/stories/impl/src/main/java/com/tangem/features/stories/impl/di/StoriesComponentModule.kt @@ -0,0 +1,18 @@ +package com.tangem.features.stories.impl.di + +import com.tangem.features.stories.api.component.StoriesComponent +import com.tangem.features.stories.impl.DefaultStoriesComponent +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +internal interface StoriesComponentModule { + + @Binds + @Singleton + fun bindStoriesComponentFactory(factory: DefaultStoriesComponent.Factory): StoriesComponent.Factory +} diff --git a/features/stories/impl/src/main/java/com/tangem/features/stories/impl/di/StoriesFeatureModule.kt b/features/stories/impl/src/main/java/com/tangem/features/stories/impl/di/StoriesFeatureModule.kt new file mode 100644 index 0000000000..be7f4349ec --- /dev/null +++ b/features/stories/impl/src/main/java/com/tangem/features/stories/impl/di/StoriesFeatureModule.kt @@ -0,0 +1,21 @@ +package com.tangem.features.stories.impl.di + +import com.tangem.core.configtoggle.feature.FeatureTogglesManager +import com.tangem.features.stories.api.StoriesFeatureToggles +import com.tangem.features.stories.impl.DefaultStoriesFeatureToggles +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +internal object StoriesFeatureModule { + + @Provides + @Singleton + fun provideStoriesFeatureToggles(featureTogglesManager: FeatureTogglesManager): StoriesFeatureToggles { + return DefaultStoriesFeatureToggles(featureTogglesManager) + } +} diff --git a/features/stories/impl/src/main/java/com/tangem/features/stories/impl/ui/StoriesComponentContent.kt b/features/stories/impl/src/main/java/com/tangem/features/stories/impl/ui/StoriesComponentContent.kt new file mode 100644 index 0000000000..3824d32495 --- /dev/null +++ b/features/stories/impl/src/main/java/com/tangem/features/stories/impl/ui/StoriesComponentContent.kt @@ -0,0 +1,9 @@ +package com.tangem.features.stories.impl.ui + +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable + +@Composable +fun StoriesComponentContent() { + Text("Stories!") +} diff --git a/settings.gradle.kts b/settings.gradle.kts index d952775d64..7467b0596c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -205,6 +205,9 @@ include(":features:markets:impl") include(":features:onramp:api") include(":features:onramp:impl") + +include(":features:stories:api") +include(":features:stories:impl") // endregion Feature modules // region Domain modules