Initial commit
Some checks failed
CI / build (push) Has been cancelled

This commit is contained in:
2026-06-11 11:03:01 +02:00
commit d1ff0e30ba
138 changed files with 5658 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
package com.example.architecture
import android.app.Application
import com.example.architecture.core.data.di.coreDataModule
import com.example.architecture.feature.about.presentation.di.aboutPresentationModule
import com.example.architecture.feature.characters.data.di.charactersDataModule
import com.example.architecture.feature.characters.presentation.di.charactersPresentationModule
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.core.context.startKoin
import timber.log.Timber
/**
* Single Koin entry point. Every feature's `*DataModule` / `*PresentationModule` is assembled here,
* never inside feature modules.
*/
class ArchitectureApp : Application() {
override fun onCreate() {
super.onCreate()
// Plant Timber only in debug; release builds get no logs (swap in a crash-reporting tree).
if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree())
}
startKoin {
androidLogger()
androidContext(this@ArchitectureApp)
modules(
// core
coreDataModule,
// characters feature
charactersDataModule,
charactersPresentationModule,
// about feature (MVVM contrast)
aboutPresentationModule,
)
}
}
}

View File

@@ -0,0 +1,11 @@
package com.example.architecture
import kotlinx.serialization.Serializable
/**
* Route for the characters list rendered with the classic **Views** toolkit. It lives in `:app`
* because `:app` owns Compose↔View interop - the `:feature:characters:presentation-views` module
* stays navigation-agnostic (it knows nothing about Compose Navigation or this route).
*/
@Serializable
data object CharactersViewsRoute

View File

@@ -0,0 +1,60 @@
package com.example.architecture
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.fragment.app.FragmentActivity
import androidx.fragment.compose.AndroidFragment
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.example.architecture.core.design.system.theme.AppTheme
import com.example.architecture.feature.about.presentation.AboutRoute
import com.example.architecture.feature.about.presentation.aboutGraph
import com.example.architecture.feature.characters.presentation.compose.CharacterDetailRoute
import com.example.architecture.feature.characters.presentation.compose.CharacterListRoute
import com.example.architecture.feature.characters.presentation.compose.charactersGraph
import com.example.architecture.feature.characters.presentation.views.CharacterListFragment
/**
* Hosts the single Compose NavHost and owns every cross-feature / cross-toolkit wiring:
* - the characters graph (Compose list + detail),
* - the About graph (MVVM contrast),
* - the Views renderer embedded via [AndroidFragment] (Compose↔View interop).
*
* Extends [FragmentActivity] (not plain ComponentActivity) so [AndroidFragment] has a FragmentManager.
*/
class MainActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
AppTheme {
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = CharacterListRoute,
) {
charactersGraph(
navController = navController,
onOpenAbout = { navController.navigate(AboutRoute) },
onOpenViewsList = { navController.navigate(CharactersViewsRoute) },
)
aboutGraph(
onNavigateBack = { navController.popBackStack() },
)
// Compose↔View interop: the same characters list, rendered by a Fragment. :app
// injects the navigation callbacks so the Views module stays nav-agnostic.
composable<CharactersViewsRoute> {
AndroidFragment<CharacterListFragment> { fragment ->
fragment.onCharacterClick = { id ->
navController.navigate(CharacterDetailRoute(id))
}
fragment.onNavigateBack = { navController.popBackStack() }
}
}
}
}
}
}
}