diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 9ea56bf..f0a23c9 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,26 +1,20 @@
-import com.loodos.buildsrc.getDateTime
-
-// TODO: Remove once https://youtrack.jetbrains.com/issue/KTIJ-19369 is fixed
-@Suppress("DSL_SCOPE_VIOLATION")
plugins {
- kotlin("kapt")
- alias(libs.plugins.android.application)
- alias(libs.plugins.kotlin.android)
- alias(libs.plugins.dagger.hilt)
- alias(libs.plugins.kotlinter)
+ id("samplecomposeanroid.android.application")
+ id("samplecomposeanroid.android.application.compose")
+ id("samplecomposeanroid.android.room")
+ id("samplecomposeanroid.android.hilt")
+ id("samplecomposeanroid.kotlinter")
}
android {
- namespace = "com.loodos.samplecomposeandroid"
- compileSdk = 33
-
+ buildFeatures {
+ buildConfig = true
+ }
defaultConfig {
applicationId = "com.loodos.samplecomposeandroid"
- minSdk = 21
- targetSdk = 33
versionCode = 1
versionName = "1.0"
- flavorDimensions("version")
+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
@@ -36,13 +30,14 @@ android {
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
+
}
getByName("debug") {
- isMinifyEnabled = false
isDebuggable = true
+ isMinifyEnabled = false
isShrinkResources = false
- versionNameSuffix = ".${getDateTime()}"
+ enableUnitTestCoverage = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
@@ -50,112 +45,61 @@ android {
}
}
- productFlavors {
- create("dev") {
- dimension = "version"
- applicationIdSuffix = ".dev"
- versionNameSuffix = "-dev"
- resValue("string", "app_name", "Sample Compose Android Dev")
- buildConfigField("String", "BASE_URL", "\"https://fakestoreapi.com/\"")
-
- }
- create("prod") {
- dimension = "version"
- applicationIdSuffix = ".prod"
- versionNameSuffix = "-prod"
- resValue("string", "app_name", "Sample Compose Android")
- buildConfigField("String", "BASE_URL", "\"https://fakestoreapi.com/\"")
-
- }
- }
-
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_17
- targetCompatibility = JavaVersion.VERSION_17
- }
- kotlinOptions {
- jvmTarget = "17"
- }
- buildFeatures {
- buildConfig = true
- compose = true
- }
- composeOptions {
- kotlinCompilerExtensionVersion = "1.4.7"
- }
packagingOptions {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
- lint {
- baseline = file("lint-baseline.xml")
- }
-}
+ namespace = "com.loodos.samplecomposeandroid"
+}
dependencies {
- val composeBom = platform(libs.androidx.compose.bom)
- implementation(composeBom)
- androidTestImplementation(composeBom)
-
+ implementation(libs.accompanist.systemuicontroller)
implementation(libs.androidx.activity.compose)
- implementation(libs.androidx.compose.ui)
-
- implementation(libs.androidx.compose.material3)
+ implementation(libs.androidx.appcompat)
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.lifecycle.runtime.ktx)
+ implementation(libs.android.material)
+ implementation(libs.compose.ui)
+ implementation(libs.compose.material)
implementation(libs.androidx.compose.material.iconsExtended)
+ implementation(libs.compose.ui.tooling)
+ implementation(libs.square.moshi.kotlin)
+ implementation(libs.square.retrofit)
+ implementation(libs.square.retrofit.converter.moshi)
+ implementation(libs.androidx.core.splashscreen)
+ implementation(libs.okhttp.logging.interceptor)
- implementation(libs.androidx.compose.ui.tooling.preview)
- debugImplementation(libs.androidx.compose.ui.tooling)
- debugImplementation(libs.androidx.compose.ui.testManifest)
-
- implementation(libs.androidx.ktx)
- implementation(libs.androidx.lifecycle.runtime.ktx)
- implementation(libs.androidx.lifecycle.runtimeCompose)
+ implementation(projects.core.common)
+ implementation(projects.core.designsystem)
+ implementation(projects.core.data)
+ implementation(projects.core.domain)
- //Splash
- implementation(libs.androidx.core.splashscreen)
+ testImplementation(libs.junit4)
- //Hilt
- implementation(libs.hilt.android)
- kapt(libs.hilt.compiler)
+ androidTestImplementation(libs.androidx.test.junit)
+ androidTestImplementation(libs.androidx.test.espresso.core)
+ androidTestImplementation(libs.compose.ui.test.junit)
+ androidTestImplementation(libs.hilt.android.testing)
implementation(libs.androidx.hilt.navigation.compose)
- // lint
- lintChecks(libs.lint.checks)
- // compose state events
- implementation(libs.compose.state.events)
- // Retrofit
- implementation(libs.retrofit)
+ debugImplementation(libs.compose.ui.test.manifest)
+ debugImplementation(libs.compose.ui.tooling)
+ debugImplementation(libs.square.leakcanary)
implementation(libs.retrofit.converter.gson)
- implementation(libs.okhttp)
- implementation(libs.okhttp.logging.interceptor)
- // chucker
+ kapt(libs.square.moshi.kotlin.codegen)
+
debugImplementation(libs.chucker)
releaseImplementation(libs.chucker.no.op)
+ implementation(libs.androidx.compose.runtime)
+ implementation(libs.androidx.lifecycle.runtime.ktx)
+ implementation(libs.androidx.lifecycle.runtimeCompose)
+ implementation(libs.compose.state.events)
+ implementation(libs.androidx.fragment.ktx)
+ implementation(libs.androidx.navigation.compose)
- testImplementation(libs.turbine)
- testImplementation(libs.truth)
-
- // To use the androidx.test.core APIs
- androidTestImplementation(libs.androidx.test.core)
- // Kotlin extensions for androidx.test.core
- androidTestImplementation(libs.androidx.test.ktx)
-
- // To use the JUnit Extension APIs
- testImplementation(libs.androidx.test.ext)
- // Kotlin extensions for androidx.test.ext.junit
- testImplementation(libs.androidx.test.ext.ktx)
-
- // To use the Truth Extension APIs
- testImplementation(libs.truth.ext)
- testImplementation(libs.jetbrains.kotlin.test)
- implementation(libs.androidx.navigation.testing)
- testImplementation(libs.junit4)
- androidTestImplementation(libs.androidx.test.ext)
- androidTestImplementation(libs.androidx.test.espresso.core)
- androidTestImplementation(libs.androidx.compose.ui.test)
}
\ No newline at end of file
diff --git a/app/src/androidTest/java/com/loodos/samplecomposeandroid/util/TestNetworkMonitor.kt b/app/src/androidTest/java/com/loodos/samplecomposeandroid/util/TestNetworkMonitor.kt
index 7956fd4..0e90480 100644
--- a/app/src/androidTest/java/com/loodos/samplecomposeandroid/util/TestNetworkMonitor.kt
+++ b/app/src/androidTest/java/com/loodos/samplecomposeandroid/util/TestNetworkMonitor.kt
@@ -1,6 +1,6 @@
package com.loodos.samplecomposeandroid.util
-import com.loodos.samplecomposeandroid.core.util.NetworkMonitor
+import com.loodos.data.util.NetworkMonitor
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
@@ -8,7 +8,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
* Created by mertcantoptas on 21.03.2023
*/
-class TestNetworkMonitor : NetworkMonitor {
+class TestNetworkMonitor : com.loodos.data.util.NetworkMonitor {
private val connectivityFlow = MutableStateFlow(true)
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/feature/appstate/MainApp.kt b/app/src/main/java/com/loodos/samplecomposeandroid/feature/appstate/MainApp.kt
index b1bd881..7de81db 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/feature/appstate/MainApp.kt
+++ b/app/src/main/java/com/loodos/samplecomposeandroid/feature/appstate/MainApp.kt
@@ -25,14 +25,12 @@ import androidx.compose.ui.semantics.testTagsAsResourceId
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavDestination
import androidx.navigation.NavDestination.Companion.hierarchy
+import com.loodos.data.util.NetworkMonitor
+import com.loodos.designsystems.component.MainAppScaffold
+import com.loodos.designsystems.icon.Icon
import com.loodos.samplecomposeandroid.R
-import com.loodos.samplecomposeandroid.core.designsystem.icon.Icon
-import com.loodos.samplecomposeandroid.core.designsystem.slideIn
-import com.loodos.samplecomposeandroid.core.designsystem.slideOut
-import com.loodos.samplecomposeandroid.core.util.NetworkMonitor
-import com.loodos.samplecomposeandroid.feature.navigation.MainNavHost
-import com.loodos.samplecomposeandroid.feature.navigation.TopLevelDestination
-import com.loodos.samplecomposeandroid.ui.components.MainAppScaffold
+import com.loodos.samplecomposeandroid.navigation.MainNavHost
+import com.loodos.samplecomposeandroid.navigation.TopLevelDestination
/**
* Created by mertcantoptas on 10.03.2023
@@ -68,8 +66,8 @@ fun MainApp(
bottomBar = {
AnimatedVisibility(
visible = appState.shouldShowBottomBar,
- enter = slideIn,
- exit = slideOut,
+ enter = com.loodos.designsystems.animation.slideIn,
+ exit = com.loodos.designsystems.animation.slideOut,
) {
AppNavBar(
destinations = AppDestinations(appState.topLevelDestinations),
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/feature/appstate/MainAppState.kt b/app/src/main/java/com/loodos/samplecomposeandroid/feature/appstate/MainAppState.kt
index 272ae68..a5c6699 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/feature/appstate/MainAppState.kt
+++ b/app/src/main/java/com/loodos/samplecomposeandroid/feature/appstate/MainAppState.kt
@@ -10,12 +10,12 @@ import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navOptions
-import com.loodos.samplecomposeandroid.core.util.NetworkMonitor
+import com.loodos.data.util.NetworkMonitor
import com.loodos.samplecomposeandroid.feature.category.navigateToCategory
import com.loodos.samplecomposeandroid.feature.home.navigation.HomeNavigationRoute
import com.loodos.samplecomposeandroid.feature.home.navigation.navigateToHome
-import com.loodos.samplecomposeandroid.feature.navigation.TopLevelDestination
import com.loodos.samplecomposeandroid.feature.profile.navigateToProfile
+import com.loodos.samplecomposeandroid.navigation.TopLevelDestination
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
@@ -27,7 +27,7 @@ import kotlinx.coroutines.flow.stateIn
@Composable
fun rememberMainAppState(
- networkMonitor: NetworkMonitor,
+ networkMonitor: com.loodos.data.util.NetworkMonitor,
coroutineScope: CoroutineScope = rememberCoroutineScope(),
navController: NavHostController = rememberNavController(),
): MainAppState {
@@ -40,7 +40,7 @@ fun rememberMainAppState(
class MainAppState(
val navController: NavHostController,
val coroutineScope: CoroutineScope,
- networkMonitor: NetworkMonitor,
+ networkMonitor: com.loodos.data.util.NetworkMonitor,
) {
val currentDestination: NavDestination?
@Composable get() = navController
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/feature/home/HomeScreen.kt b/app/src/main/java/com/loodos/samplecomposeandroid/feature/home/HomeScreen.kt
index 9d7dc5e..d12fb15 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/feature/home/HomeScreen.kt
+++ b/app/src/main/java/com/loodos/samplecomposeandroid/feature/home/HomeScreen.kt
@@ -32,7 +32,6 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.loodos.samplecomposeandroid.R
-import com.loodos.samplecomposeandroid.ui.components.MainAppScaffold
import de.palm.composestateevents.EventEffect
/**
@@ -65,7 +64,7 @@ fun HomeScreen(
onProductClick: (ProductItem) -> Unit,
modifier: Modifier = Modifier,
) {
- MainAppScaffold(
+ com.loodos.designsystems.component.MainAppScaffold(
modifier = modifier.fillMaxSize(),
topBar = {
CenterAlignedTopAppBar(
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/feature/login/LoginScreen.kt b/app/src/main/java/com/loodos/samplecomposeandroid/feature/login/LoginScreen.kt
index 8843d97..3f3489c 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/feature/login/LoginScreen.kt
+++ b/app/src/main/java/com/loodos/samplecomposeandroid/feature/login/LoginScreen.kt
@@ -35,9 +35,6 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.loodos.samplecomposeandroid.R
-import com.loodos.samplecomposeandroid.ui.components.CustomTextField
-import com.loodos.samplecomposeandroid.ui.components.MainAppScaffold
-import com.loodos.samplecomposeandroid.ui.theme.SampleComposeAndroidTheme
import de.palm.composestateevents.EventEffect
/**
@@ -75,7 +72,7 @@ fun LoginScreen(
modifier: Modifier = Modifier,
onLoginClicked: () -> Unit,
) {
- MainAppScaffold(
+ com.loodos.designsystems.component.MainAppScaffold(
modifier = modifier.fillMaxSize(),
) {
Content(
@@ -140,7 +137,7 @@ private fun UserNameTextField(
onValueChange: (String) -> Unit,
modifier: Modifier = Modifier,
) {
- CustomTextField(
+ com.loodos.designsystems.component.CustomTextField(
modifier = modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
@@ -183,7 +180,7 @@ private fun PasswordTextField(
modifier: Modifier = Modifier,
) {
var isPasswordVisible by remember { mutableStateOf(false) }
- CustomTextField(
+ com.loodos.designsystems.component.CustomTextField(
modifier = modifier
.fillMaxWidth()
.padding(horizontal = 16.dp),
@@ -229,7 +226,7 @@ private fun PasswordTextField(
@Preview(showBackground = true)
@Composable
fun LoginScreenPreview() {
- SampleComposeAndroidTheme() {
+ com.loodos.designsystems.theme.SampleComposeAndroidTheme() {
Content(
LoginViewState(),
onUserNameValueChange = {},
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/feature/login/LoginViewModel.kt b/app/src/main/java/com/loodos/samplecomposeandroid/feature/login/LoginViewModel.kt
index 869372a..0e5d4a8 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/feature/login/LoginViewModel.kt
+++ b/app/src/main/java/com/loodos/samplecomposeandroid/feature/login/LoginViewModel.kt
@@ -1,17 +1,17 @@
package com.loodos.samplecomposeandroid.feature.login
import androidx.lifecycle.viewModelScope
+import com.loodos.common.result.Resource
+import com.loodos.common.result.asResource
+import com.loodos.domain.login.LoginUseCase
+import com.loodos.domain.login.ValidateAuthUseCase
import com.loodos.samplecomposeandroid.R
import com.loodos.samplecomposeandroid.arch.BaseViewModel
import com.loodos.samplecomposeandroid.arch.IViewState
-import com.loodos.samplecomposeandroid.core.common.Resource
-import com.loodos.samplecomposeandroid.core.common.asResource
import com.loodos.samplecomposeandroid.core.domain.PasswordLengthException
import com.loodos.samplecomposeandroid.core.domain.PasswordRequiredException
import com.loodos.samplecomposeandroid.core.domain.UsernameLengthException
import com.loodos.samplecomposeandroid.core.domain.UsernameRequiredException
-import com.loodos.samplecomposeandroid.core.domain.login.LoginUseCase
-import com.loodos.samplecomposeandroid.core.domain.login.ValidateAuthUseCase
import dagger.hilt.android.lifecycle.HiltViewModel
import de.palm.composestateevents.StateEvent
import de.palm.composestateevents.StateEventWithContent
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/feature/main/MainActivity.kt b/app/src/main/java/com/loodos/samplecomposeandroid/feature/main/MainActivity.kt
index 96bd901..e8f6c9d 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/feature/main/MainActivity.kt
+++ b/app/src/main/java/com/loodos/samplecomposeandroid/feature/main/MainActivity.kt
@@ -17,9 +17,8 @@ import androidx.core.view.WindowCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
-import com.loodos.samplecomposeandroid.core.util.NetworkMonitor
+import com.loodos.data.util.NetworkMonitor
import com.loodos.samplecomposeandroid.feature.appstate.MainApp
-import com.loodos.samplecomposeandroid.ui.theme.SampleComposeAndroidTheme
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.onEach
@@ -30,7 +29,7 @@ import javax.inject.Inject
class MainActivity : ComponentActivity() {
@Inject
- lateinit var networkMonitor: NetworkMonitor
+ lateinit var networkMonitor: com.loodos.data.util.NetworkMonitor
companion object {
const val splashFadeDurationMillis = 1000L
@@ -84,7 +83,7 @@ class MainActivity : ComponentActivity() {
private fun setContent() {
setContent {
- SampleComposeAndroidTheme {
+ com.loodos.designsystems.theme.SampleComposeAndroidTheme {
MainApp(networkMonitor = networkMonitor)
}
}
@@ -101,7 +100,7 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
- SampleComposeAndroidTheme {
+ com.loodos.designsystems.theme.SampleComposeAndroidTheme {
Greeting("Android")
}
}
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/feature/navigation/MainNavHost.kt b/app/src/main/java/com/loodos/samplecomposeandroid/navigation/MainNavHost.kt
similarity index 96%
rename from app/src/main/java/com/loodos/samplecomposeandroid/feature/navigation/MainNavHost.kt
rename to app/src/main/java/com/loodos/samplecomposeandroid/navigation/MainNavHost.kt
index 1eaef9c..0b8755d 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/feature/navigation/MainNavHost.kt
+++ b/app/src/main/java/com/loodos/samplecomposeandroid/navigation/MainNavHost.kt
@@ -1,4 +1,4 @@
-package com.loodos.samplecomposeandroid.feature.navigation
+package com.loodos.samplecomposeandroid.navigation
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/feature/navigation/TopLevelDestination.kt b/app/src/main/java/com/loodos/samplecomposeandroid/navigation/TopLevelDestination.kt
similarity index 52%
rename from app/src/main/java/com/loodos/samplecomposeandroid/feature/navigation/TopLevelDestination.kt
rename to app/src/main/java/com/loodos/samplecomposeandroid/navigation/TopLevelDestination.kt
index f3dc3c3..e4fd885 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/feature/navigation/TopLevelDestination.kt
+++ b/app/src/main/java/com/loodos/samplecomposeandroid/navigation/TopLevelDestination.kt
@@ -1,9 +1,8 @@
-package com.loodos.samplecomposeandroid.feature.navigation
+package com.loodos.samplecomposeandroid.navigation
+import com.loodos.designsystems.icon.AppIcons
+import com.loodos.designsystems.icon.Icon
import com.loodos.samplecomposeandroid.R
-import com.loodos.samplecomposeandroid.core.designsystem.icon.AppIcons
-import com.loodos.samplecomposeandroid.core.designsystem.icon.Icon
-import com.loodos.samplecomposeandroid.core.designsystem.icon.Icon.ImageVectorIcon
import com.loodos.samplecomposeandroid.feature.category.CategoryRoute
import com.loodos.samplecomposeandroid.feature.home.navigation.HomeNavigationRoute
import com.loodos.samplecomposeandroid.feature.profile.ProfileRoute
@@ -16,20 +15,20 @@ enum class TopLevelDestination(
) {
HOME(
route = HomeNavigationRoute,
- selectedIcon = ImageVectorIcon(AppIcons.Home),
- unselectedIcon = ImageVectorIcon(AppIcons.HomeOutlined),
+ selectedIcon = Icon.ImageVectorIcon(AppIcons.Home),
+ unselectedIcon = Icon.ImageVectorIcon(AppIcons.HomeOutlined),
titleTextId = R.string.nav_home_title,
),
CATEGORY(
route = CategoryRoute,
- selectedIcon = ImageVectorIcon(AppIcons.Category),
- unselectedIcon = ImageVectorIcon(AppIcons.CategoryOutlined),
+ selectedIcon = Icon.ImageVectorIcon(AppIcons.Category),
+ unselectedIcon = Icon.ImageVectorIcon(AppIcons.CategoryOutlined),
titleTextId = R.string.nav_category_title,
),
PROFILE(
route = ProfileRoute,
- selectedIcon = ImageVectorIcon(AppIcons.Person),
- unselectedIcon = ImageVectorIcon(AppIcons.PersonOutlined),
+ selectedIcon = Icon.ImageVectorIcon(AppIcons.Person),
+ unselectedIcon = Icon.ImageVectorIcon(AppIcons.PersonOutlined),
titleTextId = R.string.nav_profile_title,
),
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 30c2b27..0bdf79b 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -3,6 +3,7 @@
Username
Password
Login
+ Sample Compose
Username cannot be blank!
diff --git a/build-logic/README.md b/build-logic/README.md
new file mode 100644
index 0000000..0458b4f
--- /dev/null
+++ b/build-logic/README.md
@@ -0,0 +1,38 @@
+# Convention Plugins
+
+The `build-logic` folder defines project-specific convention plugins, used to keep a single
+source of truth for common module configurations.
+
+This approach is heavily based on
+[https://developer.squareup.com/blog/herding-elephants/](https://developer.squareup.com/blog/herding-elephants/)
+and
+[https://github.com/jjohannes/idiomatic-gradle](https://github.com/jjohannes/idiomatic-gradle).
+
+By setting up convention plugins in `build-logic`, we can avoid duplicated build script setup,
+messy `subproject` configurations, without the pitfalls of the `buildSrc` directory.
+
+`build-logic` is an included build, as configured in the root
+[`settings.gradle.kts`](../settings.gradle.kts).
+
+Inside `build-logic` is a `convention` module, which defines a set of plugins that all normal
+modules can use to configure themselves.
+
+`build-logic` also includes a set of `Kotlin` files used to share logic between plugins themselves,
+which is most useful for configuring Android components (libraries vs applications) with shared
+code.
+
+These plugins are *additive* and *composable*, and try to only accomplish a single responsibility.
+Modules can then pick and choose the configurations they need.
+If there is one-off logic for a module without shared code, it's preferable to define that directly
+in the module's `build.gradle`, as opposed to creating a convention plugin with module-specific
+setup.
+
+Current list of convention plugins:
+
+- [`nowinandroid.android.application`](convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt),
+ [`nowinandroid.android.library`](convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt),
+ [`nowinandroid.android.test`](convention/src/main/kotlin/AndroidTestConventionPlugin.kt):
+ Configures common Android and Kotlin options.
+- [`nowinandroid.android.application.compose`](convention/src/main/kotlin/AndroidApplicationComposeConventionPlugin.kt),
+ [`nowinandroid.android.library.compose`](convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt):
+ Configures Jetpack Compose options
diff --git a/build-logic/convention/build.gradle.kts b/build-logic/convention/build.gradle.kts
new file mode 100644
index 0000000..651a5b9
--- /dev/null
+++ b/build-logic/convention/build.gradle.kts
@@ -0,0 +1,85 @@
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
+plugins {
+ `kotlin-dsl`
+}
+
+group = "com.loodos.samplecomposeanroid.buildlogic"
+
+// Configure the build-logic plugins to target JDK 17
+// This matches the JDK used to build the project, and is not related to what is running on device.
+java {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+}
+tasks.withType().configureEach {
+ kotlinOptions {
+ jvmTarget = JavaVersion.VERSION_17.toString()
+ }
+}
+
+dependencies {
+ compileOnly(libs.android.gradlePlugin)
+ compileOnly(libs.kotlin.gradlePlugin)
+ compileOnly(libs.firebase.crashlytics.gradlePlugin)
+ compileOnly(libs.ksp.gradlePlugin)
+}
+
+gradlePlugin {
+ plugins {
+ register("androidApplicationCompose") {
+ id = "samplecomposeanroid.android.application.compose"
+ implementationClass = "AndroidApplicationComposeConventionPlugin"
+ }
+ register("androidApplication") {
+ id = "samplecomposeanroid.android.application"
+ implementationClass = "AndroidApplicationConventionPlugin"
+ }
+ register("androidApplicationJacoco") {
+ id = "samplecomposeanroid.android.application.jacoco"
+ implementationClass = "AndroidApplicationJacocoConventionPlugin"
+ }
+ register("androidLibraryCompose") {
+ id = "samplecomposeanroid.android.library.compose"
+ implementationClass = "AndroidLibraryComposeConventionPlugin"
+ }
+ register("androidLibrary") {
+ id = "samplecomposeanroid.android.library"
+ implementationClass = "AndroidLibraryConventionPlugin"
+ }
+ register("androidFeature") {
+ id = "samplecomposeanroid.android.feature"
+ implementationClass = "AndroidFeatureConventionPlugin"
+ }
+ register("androidLibraryJacoco") {
+ id = "samplecomposeanroid.android.library.jacoco"
+ implementationClass = "AndroidLibraryJacocoConventionPlugin"
+ }
+
+ register("androidTest") {
+ id = "samplecomposeanroid.android.test"
+ implementationClass = "AndroidTestConventionPlugin"
+ }
+ register("androidHilt") {
+ id = "samplecomposeanroid.android.hilt"
+ implementationClass = "AndroidHiltConventionPlugin"
+ }
+ register("androidRoom") {
+ id = "samplecomposeanroid.android.room"
+ implementationClass = "AndroidRoomConventionPlugin"
+ }
+ register("firebase-perf") {
+ id = "samplecomposeanroid.firebase-perf"
+ implementationClass = "FirebasePerfConventionPlugin"
+ }
+ register("androidFlavors") {
+ id = "samplecomposeanroid.android.application.flavors"
+ implementationClass = "AndroidApplicationFlavorsConventionPlugin"
+ }
+
+ register("kotlinter") {
+ id = "samplecomposeanroid.kotlinter"
+ implementationClass = "KotlinLinterPlugin"
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationComposeConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationComposeConventionPlugin.kt
new file mode 100644
index 0000000..8698abf
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/AndroidApplicationComposeConventionPlugin.kt
@@ -0,0 +1,16 @@
+import com.android.build.api.dsl.ApplicationExtension
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.getByType
+import samplecomposeandroid.configureAndroidCompose
+
+class AndroidApplicationComposeConventionPlugin : Plugin {
+ override fun apply(target: Project) {
+ with(target) {
+ pluginManager.apply("com.android.application")
+ val extension = extensions.getByType()
+ configureAndroidCompose(extension)
+ }
+ }
+
+}
diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt
new file mode 100644
index 0000000..1a17097
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt
@@ -0,0 +1,33 @@
+import com.android.build.api.dsl.ApplicationExtension
+import com.android.build.api.variant.ApplicationAndroidComponentsExtension
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.getByType
+import samplecomposeandroid.configureFlavors
+import samplecomposeandroid.configureKotlinAndroid
+import samplecomposeandroid.configurePrintApksTask
+
+class AndroidApplicationConventionPlugin : Plugin {
+ override fun apply(target: Project) {
+ with(target) {
+ with(pluginManager) {
+ apply("com.android.application")
+ apply("org.jetbrains.kotlin.android")
+ }
+
+ val libs = extensions.getByType().named("libs")
+
+ extensions.configure {
+ configureKotlinAndroid(this)
+ defaultConfig.targetSdk = libs.findVersion("compileSdk").get().toString().toInt()
+ configureFlavors(this)
+ }
+ extensions.configure {
+ configurePrintApksTask(this)
+ }
+ }
+ }
+
+}
diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationFlavorsConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationFlavorsConventionPlugin.kt
new file mode 100644
index 0000000..57ea342
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/AndroidApplicationFlavorsConventionPlugin.kt
@@ -0,0 +1,15 @@
+import com.android.build.api.dsl.ApplicationExtension
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.configure
+import samplecomposeandroid.configureFlavors
+
+class AndroidApplicationFlavorsConventionPlugin : Plugin {
+ override fun apply(target: Project) {
+ with(target) {
+ extensions.configure {
+ configureFlavors(this)
+ }
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt
new file mode 100644
index 0000000..1384a96
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import com.android.build.api.variant.ApplicationAndroidComponentsExtension
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.getByType
+import samplecomposeandroid.configureJacoco
+
+class AndroidApplicationJacocoConventionPlugin : Plugin {
+ override fun apply(target: Project) {
+ with(target) {
+ with(pluginManager) {
+ apply("org.gradle.jacoco")
+ apply("com.android.application")
+ }
+ val extension = extensions.getByType()
+ configureJacoco(extension)
+ }
+ }
+
+}
diff --git a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt
new file mode 100644
index 0000000..773a765
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt
@@ -0,0 +1,50 @@
+import com.android.build.gradle.LibraryExtension
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.getByType
+import org.gradle.kotlin.dsl.kotlin
+
+class AndroidFeatureConventionPlugin : Plugin {
+ override fun apply(target: Project) {
+ with(target) {
+ pluginManager.apply {
+ apply("samplecomposeanroid.android.library")
+ apply("samplecomposeanroid.android.hilt")
+ }
+ extensions.configure {
+ defaultConfig {
+ testInstrumentationRunner =
+ "samplecomposeanroid.core.testing.NiaTestRunner"
+ }
+ }
+
+ val libs = extensions.getByType().named("libs")
+
+ dependencies {
+ add("implementation", project(":core:model"))
+ add("implementation", project(":core:ui"))
+ add("implementation", project(":core:designsystem"))
+ add("implementation", project(":core:data"))
+ add("implementation", project(":core:common"))
+ add("implementation", project(":core:domain"))
+
+ add("testImplementation", kotlin("test"))
+ add("testImplementation", project(":core:testing"))
+ add("androidTestImplementation", kotlin("test"))
+ add("androidTestImplementation", project(":core:testing"))
+
+ add("implementation", libs.findLibrary("coil.kt").get())
+ add("implementation", libs.findLibrary("coil.kt.compose").get())
+
+ add("implementation", libs.findLibrary("androidx.hilt.navigation.compose").get())
+ add("implementation", libs.findLibrary("androidx.lifecycle.runtimeCompose").get())
+ add("implementation", libs.findLibrary("androidx.lifecycle.viewModelCompose").get())
+
+ add("implementation", libs.findLibrary("kotlinx.coroutines.android").get())
+ }
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/AndroidHiltConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidHiltConventionPlugin.kt
new file mode 100644
index 0000000..9e374aa
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/AndroidHiltConventionPlugin.kt
@@ -0,0 +1,24 @@
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.getByType
+
+class AndroidHiltConventionPlugin : Plugin {
+ override fun apply(target: Project) {
+ with(target) {
+ with(pluginManager) {
+ apply("org.jetbrains.kotlin.kapt")
+ apply("dagger.hilt.android.plugin")
+ }
+
+ val libs = extensions.getByType().named("libs")
+ dependencies {
+ "implementation"(libs.findLibrary("hilt.android").get())
+ "kapt"(libs.findLibrary("hilt.compiler").get())
+ "kaptAndroidTest"(libs.findLibrary("hilt.compiler").get())
+ }
+
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt
new file mode 100644
index 0000000..cbcbcb7
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/AndroidLibraryComposeConventionPlugin.kt
@@ -0,0 +1,15 @@
+import com.android.build.gradle.LibraryExtension
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.getByType
+import samplecomposeandroid.configureAndroidCompose
+
+class AndroidLibraryComposeConventionPlugin : Plugin {
+ override fun apply(target: Project) {
+ with(target) {
+ pluginManager.apply("com.android.library")
+ val extension = extensions.getByType()
+ configureAndroidCompose(extension)
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt
new file mode 100644
index 0000000..fcf0160
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt
@@ -0,0 +1,44 @@
+import com.android.build.api.variant.LibraryAndroidComponentsExtension
+import com.android.build.gradle.LibraryExtension
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.getByType
+import org.gradle.kotlin.dsl.kotlin
+import samplecomposeandroid.configureFlavors
+import samplecomposeandroid.configureKotlinAndroid
+import samplecomposeandroid.configurePrintApksTask
+
+class AndroidLibraryConventionPlugin : Plugin {
+ override fun apply(target: Project) {
+ with(target) {
+ with(pluginManager) {
+ apply("com.android.library")
+ apply("org.jetbrains.kotlin.android")
+ }
+
+ val libs = extensions.getByType().named("libs")
+
+ extensions.configure {
+ defaultConfig.targetSdk = libs.findVersion("targetSdk").get().toString().toInt()
+ configureKotlinAndroid(this)
+ configureFlavors(this)
+ }
+ extensions.configure {
+ configurePrintApksTask(this)
+ }
+ configurations.configureEach {
+ resolutionStrategy {
+ force(libs.findLibrary("junit4").get())
+ force("org.objenesis:objenesis:2.6")
+ }
+ }
+ dependencies {
+ add("androidTestImplementation", kotlin("test"))
+ add("testImplementation", kotlin("test"))
+ }
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt
new file mode 100644
index 0000000..bb35a7d
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt
@@ -0,0 +1,19 @@
+import com.android.build.api.variant.LibraryAndroidComponentsExtension
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.kotlin.dsl.getByType
+import samplecomposeandroid.configureJacoco
+
+class AndroidLibraryJacocoConventionPlugin : Plugin {
+ override fun apply(target: Project) {
+ with(target) {
+ with(pluginManager) {
+ apply("org.gradle.jacoco")
+ apply("com.android.library")
+ }
+ val extension = extensions.getByType()
+ configureJacoco(extension)
+ }
+ }
+
+}
diff --git a/build-logic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt
new file mode 100644
index 0000000..852dd48
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt
@@ -0,0 +1,48 @@
+import com.google.devtools.ksp.gradle.KspExtension
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.api.tasks.InputDirectory
+import org.gradle.api.tasks.PathSensitive
+import org.gradle.api.tasks.PathSensitivity
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.getByType
+import org.gradle.process.CommandLineArgumentProvider
+import java.io.File
+
+class AndroidRoomConventionPlugin : Plugin {
+
+ override fun apply(target: Project) {
+ with(target) {
+ pluginManager.apply("com.google.devtools.ksp")
+
+ extensions.configure {
+ // The schemas directory contains a schema file for each version of the Room database.
+ // This is required to enable Room auto migrations.
+ // See https://developer.android.com/reference/kotlin/androidx/room/AutoMigration.
+// arg(RoomSchemaArgProvider(File(projectDir, "schemas")))
+ }
+
+ val libs = extensions.getByType().named("libs")
+ dependencies {
+ add("implementation", libs.findLibrary("androidx.room.runtime").get())
+ add("implementation", libs.findLibrary("androidx.room.ktx").get())
+ add("implementation", libs.findLibrary("androidx.room.paging").get())
+ add("ksp", libs.findLibrary("androidx.room.compiler").get())
+ }
+ }
+ }
+
+ /**
+ * https://issuetracker.google.com/issues/132245929
+ * [Export schemas](https://developer.android.com/training/data-storage/room/migrating-db-versions#export-schemas)
+ */
+ class RoomSchemaArgProvider(
+ @get:InputDirectory
+ @get:PathSensitive(PathSensitivity.RELATIVE)
+ val schemaDir: File,
+ ) : CommandLineArgumentProvider {
+ override fun asArguments() = listOf("room.schemaLocation=${schemaDir.path}")
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt
new file mode 100644
index 0000000..8e11033
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt
@@ -0,0 +1,25 @@
+import com.android.build.gradle.TestExtension
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.getByType
+import samplecomposeandroid.configureKotlinAndroid
+
+class AndroidTestConventionPlugin : Plugin {
+ override fun apply(target: Project) {
+ with(target) {
+ with(pluginManager) {
+ apply("com.android.test")
+ apply("org.jetbrains.kotlin.android")
+ }
+ val libs = extensions.getByType().named("libs")
+
+ extensions.configure {
+ configureKotlinAndroid(this)
+ defaultConfig.targetSdk = libs.findVersion("targetSdk").get().toString().toInt()
+ }
+ }
+ }
+
+}
diff --git a/build-logic/convention/src/main/kotlin/FirebasePerfConventionPlugin.kt b/build-logic/convention/src/main/kotlin/FirebasePerfConventionPlugin.kt
new file mode 100644
index 0000000..1b855c1
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/FirebasePerfConventionPlugin.kt
@@ -0,0 +1,15 @@
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.kotlin.dsl.getByType
+
+class FirebasePerfConventionPlugin : Plugin {
+ override fun apply(target: Project) {
+ with(target) {
+ val libs = extensions.getByType().named("libs")
+ pluginManager.findPlugin("com.google.firebase.firebase-perf").apply {
+ version = libs.findVersion("firebase-pref").get().toString()
+ }
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/KotlinLinterPlugin.kt b/build-logic/convention/src/main/kotlin/KotlinLinterPlugin.kt
new file mode 100644
index 0000000..96dd2da
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/KotlinLinterPlugin.kt
@@ -0,0 +1,11 @@
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+
+class KotlinLinterPlugin : Plugin {
+ override fun apply(target: Project) {
+ with(target) {
+ pluginManager.apply("org.jmailen.kotlinter")
+ }
+ }
+
+}
diff --git a/build-logic/convention/src/main/kotlin/samplecomposeandroid/AndroidCompose.kt b/build-logic/convention/src/main/kotlin/samplecomposeandroid/AndroidCompose.kt
new file mode 100644
index 0000000..d18fc61
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/samplecomposeandroid/AndroidCompose.kt
@@ -0,0 +1,61 @@
+package samplecomposeandroid
+
+import com.android.build.api.dsl.CommonExtension
+import org.gradle.api.Project
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.getByType
+import java.io.File
+
+/**
+ * Configure Compose-specific options
+ */
+internal fun Project.configureAndroidCompose(
+ commonExtension: CommonExtension<*, *, *, *>,
+) {
+ val libs = extensions.getByType().named("libs")
+
+ commonExtension.apply {
+ buildFeatures {
+ compose = true
+ }
+
+ composeOptions {
+ kotlinCompilerExtensionVersion = libs.findVersion("composeCompiler").get().toString()
+ }
+
+ kotlinOptions {
+ freeCompilerArgs = freeCompilerArgs + buildComposeMetricsParameters()
+ }
+
+ dependencies {
+ val bom = libs.findLibrary("compose-bom").get()
+ add("implementation", platform(bom))
+ add("androidTestImplementation", platform(bom))
+ }
+ }
+}
+
+private fun Project.buildComposeMetricsParameters(): List {
+ val metricParameters = mutableListOf()
+ val enableMetricsProvider = project.providers.gradleProperty("enableComposeCompilerMetrics")
+ val enableMetrics = (enableMetricsProvider.orNull == "true")
+ if (enableMetrics) {
+ val metricsFolder = File(project.buildDir, "compose-metrics")
+ metricParameters.add("-P")
+ metricParameters.add(
+ "plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" + metricsFolder.absolutePath
+ )
+ }
+
+ val enableReportsProvider = project.providers.gradleProperty("enableComposeCompilerReports")
+ val enableReports = (enableReportsProvider.orNull == "true")
+ if (enableReports) {
+ val reportsFolder = File(project.buildDir, "compose-reports")
+ metricParameters.add("-P")
+ metricParameters.add(
+ "plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" + reportsFolder.absolutePath
+ )
+ }
+ return metricParameters.toList()
+}
diff --git a/build-logic/convention/src/main/kotlin/samplecomposeandroid/Flavor.kt b/build-logic/convention/src/main/kotlin/samplecomposeandroid/Flavor.kt
new file mode 100644
index 0000000..b30bbf8
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/samplecomposeandroid/Flavor.kt
@@ -0,0 +1,38 @@
+package samplecomposeandroid
+
+import com.android.build.api.dsl.ApplicationExtension
+import com.android.build.api.dsl.ApplicationProductFlavor
+import com.android.build.api.dsl.CommonExtension
+import org.gradle.api.Project
+
+enum class FlavorDimension {
+ CONTENT_TYPE
+}
+
+// The content for the app can either come from local static data which is useful for demo
+// purposes, or from a production backend server which supplies up-to-date, real content.
+// These two product flavors reflect this behaviour.
+enum class Flavor (val dimension : FlavorDimension, val applicationIdSuffix : String? = null) {
+ DEMO(FlavorDimension.CONTENT_TYPE),
+ PROD(FlavorDimension.CONTENT_TYPE, ".prod")
+}
+
+fun Project.configureFlavors(
+ commonExtension: CommonExtension<*, *, *, *>
+) {
+ commonExtension.apply {
+ flavorDimensions += FlavorDimension.CONTENT_TYPE.name
+ productFlavors {
+ Flavor.values().forEach{
+ create(it.name) {
+ dimension = it.dimension.name
+ if (this@apply is ApplicationExtension && this is ApplicationProductFlavor) {
+ if (it.applicationIdSuffix != null) {
+ this.applicationIdSuffix = it.applicationIdSuffix
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/samplecomposeandroid/Jacoco.kt b/build-logic/convention/src/main/kotlin/samplecomposeandroid/Jacoco.kt
new file mode 100644
index 0000000..d65fd7d
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/samplecomposeandroid/Jacoco.kt
@@ -0,0 +1,70 @@
+package samplecomposeandroid
+
+import com.android.build.api.variant.AndroidComponentsExtension
+import org.gradle.api.Project
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.api.tasks.testing.Test
+import org.gradle.kotlin.dsl.configure
+import org.gradle.kotlin.dsl.getByType
+import org.gradle.kotlin.dsl.register
+import org.gradle.kotlin.dsl.withType
+import org.gradle.testing.jacoco.plugins.JacocoPluginExtension
+import org.gradle.testing.jacoco.plugins.JacocoTaskExtension
+import org.gradle.testing.jacoco.tasks.JacocoReport
+
+private val coverageExclusions = listOf(
+ // Android
+ "**/R.class",
+ "**/R\$*.class",
+ "**/BuildConfig.*",
+ "**/Manifest*.*"
+)
+
+internal fun Project.configureJacoco(
+ androidComponentsExtension: AndroidComponentsExtension<*, *, *>,
+) {
+ val libs = extensions.getByType().named("libs")
+
+ configure {
+ toolVersion = libs.findVersion("jacoco").get().toString()
+ }
+
+ val jacocoTestReport = tasks.create("jacocoTestReport")
+
+ androidComponentsExtension.onVariants { variant ->
+ val testTaskName = "test${variant.name.capitalize()}UnitTest"
+
+ val reportTask = tasks.register("jacoco${testTaskName.capitalize()}Report", JacocoReport::class) {
+ dependsOn(testTaskName)
+
+ reports {
+ xml.required.set(true)
+ html.required.set(true)
+ }
+
+ classDirectories.setFrom(
+ fileTree("$buildDir/tmp/kotlin-classes/${variant.name}") {
+ exclude(coverageExclusions)
+ }
+ )
+
+ sourceDirectories.setFrom(files("$projectDir/src/main/java", "$projectDir/src/main/kotlin"))
+ executionData.setFrom(file("$buildDir/jacoco/$testTaskName.exec"))
+ }
+
+ jacocoTestReport.dependsOn(reportTask)
+ }
+
+ tasks.withType().configureEach {
+ configure {
+ // Required for JaCoCo + Robolectric
+ // https://github.com/robolectric/robolectric/issues/2230
+ // TODO: Consider removing if not we don't add Robolectric
+ isIncludeNoLocationClasses = true
+
+ // Required for JDK 11 with the above
+ // https://github.com/gradle/gradle/issues/5184#issuecomment-391982009
+ excludes = listOf("jdk.internal.*")
+ }
+ }
+}
diff --git a/build-logic/convention/src/main/kotlin/samplecomposeandroid/KotlinAndroid.kt b/build-logic/convention/src/main/kotlin/samplecomposeandroid/KotlinAndroid.kt
new file mode 100644
index 0000000..34da9a7
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/samplecomposeandroid/KotlinAndroid.kt
@@ -0,0 +1,62 @@
+package samplecomposeandroid
+
+import com.android.build.api.dsl.CommonExtension
+import org.gradle.api.JavaVersion
+import org.gradle.api.Project
+import org.gradle.api.artifacts.VersionCatalogsExtension
+import org.gradle.api.plugins.ExtensionAware
+import org.gradle.kotlin.dsl.dependencies
+import org.gradle.kotlin.dsl.getByType
+import org.gradle.kotlin.dsl.provideDelegate
+import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
+
+/**
+ * Configure base Kotlin with Android options
+ */
+internal fun Project.configureKotlinAndroid(
+ commonExtension: CommonExtension<*, *, *, *>,
+) {
+ commonExtension.apply {
+ val libs = extensions.getByType().named("libs")
+
+ compileSdk = libs.findVersion("compileSdk").get().toString().toInt()
+
+ defaultConfig {
+ minSdk = libs.findVersion("minSdk").get().toString().toInt()
+ }
+
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ isCoreLibraryDesugaringEnabled = true
+ }
+
+ kotlinOptions {
+ // Treat all Kotlin warnings as errors (disabled by default)
+ // Override by setting warningsAsErrors=true in your ~/.gradle/gradle.properties
+ val warningsAsErrors: String? by project
+ allWarningsAsErrors = warningsAsErrors.toBoolean()
+
+ freeCompilerArgs = freeCompilerArgs + listOf(
+ "-opt-in=kotlin.RequiresOptIn",
+ // Enable experimental coroutines APIs, including Flow
+ "-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
+ "-opt-in=kotlinx.coroutines.FlowPreview",
+ "-opt-in=kotlin.Experimental",
+ )
+
+ // Set JVM target to 17
+ jvmTarget = JavaVersion.VERSION_17.toString()
+ }
+ }
+
+ val libs = extensions.getByType().named("libs")
+
+ dependencies {
+ add("coreLibraryDesugaring", libs.findLibrary("android.desugarJdkLibs").get())
+ }
+}
+
+fun CommonExtension<*, *, *, *>.kotlinOptions(block: KotlinJvmOptions.() -> Unit) {
+ (this as ExtensionAware).extensions.configure("kotlinOptions", block)
+}
diff --git a/build-logic/convention/src/main/kotlin/samplecomposeandroid/PrintTestApks.kt b/build-logic/convention/src/main/kotlin/samplecomposeandroid/PrintTestApks.kt
new file mode 100644
index 0000000..337aa3c
--- /dev/null
+++ b/build-logic/convention/src/main/kotlin/samplecomposeandroid/PrintTestApks.kt
@@ -0,0 +1,82 @@
+package samplecomposeandroid
+
+import com.android.build.api.artifact.SingleArtifact
+import com.android.build.api.variant.AndroidComponentsExtension
+import com.android.build.api.variant.BuiltArtifactsLoader
+import com.android.build.api.variant.HasAndroidTest
+import org.gradle.api.DefaultTask
+import org.gradle.api.Project
+import org.gradle.api.file.Directory
+import org.gradle.api.file.DirectoryProperty
+import org.gradle.api.provider.ListProperty
+import org.gradle.api.provider.Property
+import org.gradle.api.tasks.Input
+import org.gradle.api.tasks.InputDirectory
+import org.gradle.api.tasks.InputFiles
+import org.gradle.api.tasks.Internal
+import org.gradle.api.tasks.TaskAction
+import java.io.File
+
+internal fun Project.configurePrintApksTask(extension: AndroidComponentsExtension<*, *, *>) {
+ extension.onVariants { variant ->
+ if (variant is HasAndroidTest) {
+ val loader = variant.artifacts.getBuiltArtifactsLoader()
+ val artifact = variant.androidTest?.artifacts?.get(SingleArtifact.APK)
+ val javaSources = variant.androidTest?.sources?.java?.all
+ val kotlinSources = variant.androidTest?.sources?.kotlin?.all
+
+ val testSources = if (javaSources != null && kotlinSources != null) {
+ javaSources.zip(kotlinSources) { javaDirs, kotlinDirs ->
+ javaDirs + kotlinDirs
+ }
+ } else javaSources ?: kotlinSources
+
+ if (artifact != null && testSources != null) {
+ tasks.register(
+ "${variant.name}PrintTestApk",
+ PrintApkLocationTask::class.java
+ ) {
+ apkFolder.set(artifact)
+ builtArtifactsLoader.set(loader)
+ variantName.set(variant.name)
+ sources.set(testSources)
+ }
+ }
+ }
+ }
+}
+
+internal abstract class PrintApkLocationTask : DefaultTask() {
+ @get:InputDirectory
+ abstract val apkFolder: DirectoryProperty
+
+ @get:InputFiles
+ abstract val sources: ListProperty
+
+ @get:Internal
+ abstract val builtArtifactsLoader: Property
+
+ @get:Input
+ abstract val variantName: Property
+
+ @TaskAction
+ fun taskAction() {
+ val hasFiles = sources.orNull?.any { directory ->
+ directory.asFileTree.files.any {
+ it.isFile && it.parentFile.path.contains("build${File.separator}generated").not()
+ }
+ } ?: throw UnsupportedOperationException("Cannot check androidTest sources")
+
+ // Don't print APK location if there are no androidTest source files
+ if (!hasFiles) {
+ return
+ }
+
+ val builtArtifacts = builtArtifactsLoader.get().load(apkFolder.get())
+ ?: throw IllegalStateException("Cannot load APKs")
+ if (builtArtifacts.elements.size != 1)
+ throw IllegalArgumentException("Expected one APK !")
+ val apk = File(builtArtifacts.elements.single().outputFile).toPath()
+ println(apk)
+ }
+}
diff --git a/build-logic/gradle.properties b/build-logic/gradle.properties
new file mode 100644
index 0000000..1c9073e
--- /dev/null
+++ b/build-logic/gradle.properties
@@ -0,0 +1,4 @@
+# Gradle properties are not passed to included builds https://github.com/gradle/gradle/issues/2534
+org.gradle.parallel=true
+org.gradle.caching=true
+org.gradle.configureondemand=true
diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts
new file mode 100644
index 0000000..de9224e
--- /dev/null
+++ b/build-logic/settings.gradle.kts
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+dependencyResolutionManagement {
+ repositories {
+ google()
+ mavenCentral()
+ }
+ versionCatalogs {
+ create("libs") {
+ from(files("../gradle/libs.versions.toml"))
+ }
+ }
+}
+
+rootProject.name = "build-logic"
+include(":convention")
diff --git a/build.gradle.kts b/build.gradle.kts
index c56e0f6..6035384 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,14 +1,19 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
-// TODO: Remove once https://youtrack.jetbrains.com/issue/KTIJ-19369 is fixed
-@Suppress("DSL_SCOPE_VIOLATION")
plugins {
alias(libs.plugins.detekt)
+ alias(libs.plugins.gradle.versions)
alias(libs.plugins.kotlinter) apply false
- alias(libs.plugins.android.application) apply false
- alias(libs.plugins.android.library) apply false
- alias(libs.plugins.kotlin.android) apply false
- alias(libs.plugins.kotlin.jvm) apply false
- alias(libs.plugins.dagger.hilt) apply false
+ alias(libs.plugins.com.android.application) apply false
+ alias(libs.plugins.kotlin.serialization) apply false
+ alias(libs.plugins.org.jetbrains.kotlin.android) apply false
+ alias(libs.plugins.dagger.hilt.android) apply false
+ alias(libs.plugins.com.android.test) apply false
+ alias(libs.plugins.google.services) apply false
+ alias(libs.plugins.firebase.crashlytics) apply false
+ alias(libs.plugins.ksp) apply false
+ alias(libs.plugins.com.android.library) apply false
+ alias(libs.plugins.secrets) apply false
+
}
apply(from = "buildscripts/githooks.gradle")
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
deleted file mode 100644
index d4aad3d..0000000
--- a/buildSrc/build.gradle.kts
+++ /dev/null
@@ -1,14 +0,0 @@
-plugins {
- `kotlin-dsl`
-}
-
-repositories {
- google()
- mavenCentral()
- gradlePluginPortal()
-}
-
-java {
- sourceCompatibility = JavaVersion.VERSION_17
- targetCompatibility = JavaVersion.VERSION_17
-}
\ No newline at end of file
diff --git a/buildSrc/src/main/java/com/loodos/buildsrc/GradleUtils.kt b/buildSrc/src/main/java/com/loodos/buildsrc/GradleUtils.kt
deleted file mode 100644
index 53e2c9d..0000000
--- a/buildSrc/src/main/java/com/loodos/buildsrc/GradleUtils.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.loodos.buildsrc
-
-import java.util.*
-
-fun getDateTime(): Long {
- val date = Date()
- return date.time
-}
diff --git a/buildSrc/.gitignore b/core/common/.gitignore
similarity index 100%
rename from buildSrc/.gitignore
rename to core/common/.gitignore
diff --git a/core/common/build.gradle.kts b/core/common/build.gradle.kts
new file mode 100644
index 0000000..01e6472
--- /dev/null
+++ b/core/common/build.gradle.kts
@@ -0,0 +1,12 @@
+plugins {
+ id("samplecomposeanroid.android.library")
+ id("samplecomposeanroid.android.hilt")
+}
+
+android {
+ namespace = "com.loodos.samplecomposeanroid.core.common"
+}
+
+dependencies {
+ implementation(libs.kotlinx.coroutines.android)
+}
\ No newline at end of file
diff --git a/core/common/consumer-rules.pro b/core/common/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
diff --git a/core/common/proguard-rules.pro b/core/common/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/core/common/proguard-rules.pro
@@ -0,0 +1,21 @@
+# 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/core/common/src/androidTest/java/com/loodos/common/ExampleInstrumentedTest.kt b/core/common/src/androidTest/java/com/loodos/common/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..b1f710f
--- /dev/null
+++ b/core/common/src/androidTest/java/com/loodos/common/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.loodos.common
+
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.ext.junit.runners.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("com.merttoptas.common.test", appContext.packageName)
+ }
+}
diff --git a/core/common/src/main/AndroidManifest.xml b/core/common/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..a5918e6
--- /dev/null
+++ b/core/common/src/main/AndroidManifest.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/core/common/src/main/java/com/loodos/common/network/AppDispatchers.kt b/core/common/src/main/java/com/loodos/common/network/AppDispatchers.kt
new file mode 100644
index 0000000..b6a67aa
--- /dev/null
+++ b/core/common/src/main/java/com/loodos/common/network/AppDispatchers.kt
@@ -0,0 +1,13 @@
+package com.loodos.common.network
+
+import javax.inject.Qualifier
+
+
+@Qualifier
+@Retention(AnnotationRetention.RUNTIME)
+annotation class Dispatcher(val appDispatcher: AppDispatchers)
+
+enum class AppDispatchers {
+ Default,
+ IO,
+}
diff --git a/core/common/src/main/java/com/loodos/common/network/di/CoroutineScopesModule.kt b/core/common/src/main/java/com/loodos/common/network/di/CoroutineScopesModule.kt
new file mode 100644
index 0000000..4480d9d
--- /dev/null
+++ b/core/common/src/main/java/com/loodos/common/network/di/CoroutineScopesModule.kt
@@ -0,0 +1,28 @@
+package com.loodos.common.network.di
+
+import com.loodos.common.network.AppDispatchers
+import com.loodos.common.network.Dispatcher
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.SupervisorJob
+import javax.inject.Qualifier
+import javax.inject.Singleton
+
+@Retention(AnnotationRetention.RUNTIME)
+@Qualifier
+annotation class ApplicationScope
+
+@Module
+@InstallIn(SingletonComponent::class)
+object CoroutineScopesModule {
+ @Provides
+ @Singleton
+ @ApplicationScope
+ fun providesCoroutineScope(
+ @Dispatcher(AppDispatchers.Default) dispatcher: CoroutineDispatcher,
+ ): CoroutineScope = CoroutineScope(SupervisorJob() + dispatcher)
+}
diff --git a/core/common/src/main/java/com/loodos/common/network/di/DispatchersModule.kt b/core/common/src/main/java/com/loodos/common/network/di/DispatchersModule.kt
new file mode 100644
index 0000000..fc8832a
--- /dev/null
+++ b/core/common/src/main/java/com/loodos/common/network/di/DispatchersModule.kt
@@ -0,0 +1,22 @@
+package com.loodos.common.network.di
+
+import com.loodos.common.network.AppDispatchers
+import com.loodos.common.network.Dispatcher
+import dagger.Module
+import dagger.Provides
+import dagger.hilt.InstallIn
+import dagger.hilt.components.SingletonComponent
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.Dispatchers
+
+@Module
+@InstallIn(SingletonComponent::class)
+object DispatchersModule {
+ @Provides
+ @Dispatcher(AppDispatchers.IO)
+ fun providesIODispatcher(): CoroutineDispatcher = Dispatchers.IO
+
+ @Provides
+ @Dispatcher(AppDispatchers.Default)
+ fun providesDefaultDispatcher(): CoroutineDispatcher = Dispatchers.Default
+}
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/common/Resource.kt b/core/common/src/main/java/com/loodos/common/result/Resource.kt
similarity index 91%
rename from app/src/main/java/com/loodos/samplecomposeandroid/core/common/Resource.kt
rename to core/common/src/main/java/com/loodos/common/result/Resource.kt
index ec3f8d4..f1c1868 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/core/common/Resource.kt
+++ b/core/common/src/main/java/com/loodos/common/result/Resource.kt
@@ -1,4 +1,4 @@
-package com.loodos.samplecomposeandroid.core.common
+package com.loodos.common.result
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
diff --git a/core/common/src/test/java/com/loodos/common/ExampleUnitTest.kt b/core/common/src/test/java/com/loodos/common/ExampleUnitTest.kt
new file mode 100644
index 0000000..bc9350b
--- /dev/null
+++ b/core/common/src/test/java/com/loodos/common/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.loodos.common
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * 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)
+ }
+}
diff --git a/core/data/.gitignore b/core/data/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/core/data/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/core/data/build.gradle.kts b/core/data/build.gradle.kts
new file mode 100644
index 0000000..20194dc
--- /dev/null
+++ b/core/data/build.gradle.kts
@@ -0,0 +1,36 @@
+plugins {
+ id("samplecomposeanroid.android.library")
+ id("samplecomposeanroid.android.hilt")
+ id("kotlinx-serialization")
+ id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
+
+}
+
+android {
+ namespace = "com.loodos.samplecomposeanroid.core.data"
+ testOptions {
+ unitTests {
+ isIncludeAndroidResources = true
+ isReturnDefaultValues = true
+ }
+ }
+}
+
+secrets {
+ defaultPropertiesFileName = "secrets.defaults.properties"
+}
+
+dependencies {
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.kotlinx.coroutines.android)
+ implementation(libs.kotlinx.serialization.json)
+ implementation(libs.kotlinx.datetime)
+ implementation(libs.retrofit.converter.gson)
+ implementation(libs.square.retrofit)
+ implementation(libs.square.retrofit.converter.moshi)
+ implementation(libs.okhttp.logging.interceptor)
+
+ debugImplementation(libs.chucker)
+ releaseImplementation(libs.chucker.no.op)
+ implementation(projects.core.common)
+}
diff --git a/core/data/consumer-rules.pro b/core/data/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
diff --git a/core/data/proguard-rules.pro b/core/data/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/core/data/proguard-rules.pro
@@ -0,0 +1,21 @@
+# 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/core/data/src/androidTest/java/com/loodos/data/ExampleInstrumentedTest.kt b/core/data/src/androidTest/java/com/loodos/data/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..ade89b0
--- /dev/null
+++ b/core/data/src/androidTest/java/com/loodos/data/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.loodos.data
+
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.ext.junit.runners.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("com.merttoptas.data.test", appContext.packageName)
+ }
+}
diff --git a/core/data/src/main/AndroidManifest.xml b/core/data/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..a5918e6
--- /dev/null
+++ b/core/data/src/main/AndroidManifest.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/di/DataModule.kt b/core/data/src/main/java/com/loodos/data/di/DataModule.kt
similarity index 64%
rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/di/DataModule.kt
rename to core/data/src/main/java/com/loodos/data/di/DataModule.kt
index 9b146e1..1b91197 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/di/DataModule.kt
+++ b/core/data/src/main/java/com/loodos/data/di/DataModule.kt
@@ -1,7 +1,7 @@
-package com.loodos.samplecomposeandroid.core.data.di
+package com.loodos.data.di
-import com.loodos.samplecomposeandroid.core.util.ConnectivityManagerNetworkMonitor
-import com.loodos.samplecomposeandroid.core.util.NetworkMonitor
+import com.loodos.data.util.ConnectivityManagerNetworkMonitor
+import com.loodos.data.util.NetworkMonitor
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/di/LoginModule.kt b/core/data/src/main/java/com/loodos/data/di/LoginModule.kt
similarity index 53%
rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/di/LoginModule.kt
rename to core/data/src/main/java/com/loodos/data/di/LoginModule.kt
index 3f5aa78..b79266e 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/di/LoginModule.kt
+++ b/core/data/src/main/java/com/loodos/data/di/LoginModule.kt
@@ -1,9 +1,9 @@
-package com.loodos.samplecomposeandroid.core.data.di
+package com.loodos.data.di
-import com.loodos.samplecomposeandroid.core.data.remote.source.AuthenticationRemoteDataSource
-import com.loodos.samplecomposeandroid.core.data.remote.source.AuthenticationRemoteDataSourceImpl
-import com.loodos.samplecomposeandroid.core.data.repository.AuthenticationRepository
-import com.loodos.samplecomposeandroid.core.data.repository.AuthenticationRepositoryImpl
+import com.loodos.data.remote.source.AuthenticationRemoteDataSource
+import com.loodos.data.remote.source.AuthenticationRemoteDataSourceImpl
+import com.loodos.data.repository.AuthenticationRepository
+import com.loodos.data.repository.AuthenticationRepositoryImpl
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/di/RemoteDataModule.kt b/core/data/src/main/java/com/loodos/data/di/RemoteDataModule.kt
similarity index 91%
rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/di/RemoteDataModule.kt
rename to core/data/src/main/java/com/loodos/data/di/RemoteDataModule.kt
index 581b220..6feadd6 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/di/RemoteDataModule.kt
+++ b/core/data/src/main/java/com/loodos/data/di/RemoteDataModule.kt
@@ -1,11 +1,11 @@
-package com.loodos.samplecomposeandroid.core.data.di
+package com.loodos.data.di
import android.content.Context
import com.chuckerteam.chucker.api.ChuckerCollector
import com.chuckerteam.chucker.api.ChuckerInterceptor
import com.chuckerteam.chucker.api.RetentionManager
-import com.loodos.samplecomposeandroid.BuildConfig
-import com.loodos.samplecomposeandroid.core.data.remote.api.AuthenticationService
+import com.loodos.data.remote.api.AuthenticationService
+import com.loodos.samplecomposeanroid.core.data.BuildConfig
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@@ -33,7 +33,7 @@ object RemoteDataModule {
okHttpClient: OkHttpClient,
gsonConverterFactory: GsonConverterFactory,
): Retrofit {
- return Retrofit.Builder().baseUrl(BuildConfig.BASE_URL)
+ return Retrofit.Builder().baseUrl(BuildConfig.BACKEND_URL)
.addConverterFactory(gsonConverterFactory)
.client(okHttpClient).build()
}
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/model/login/LoginBody.kt b/core/data/src/main/java/com/loodos/data/model/login/LoginBody.kt
similarity index 79%
rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/model/login/LoginBody.kt
rename to core/data/src/main/java/com/loodos/data/model/login/LoginBody.kt
index f163812..19fbd28 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/model/login/LoginBody.kt
+++ b/core/data/src/main/java/com/loodos/data/model/login/LoginBody.kt
@@ -1,4 +1,4 @@
-package com.loodos.samplecomposeandroid.core.data.model.login
+package com.loodos.data.model.login
import com.google.gson.annotations.SerializedName
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/model/login/LoginResponse.kt b/core/data/src/main/java/com/loodos/data/model/login/LoginResponse.kt
similarity index 62%
rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/model/login/LoginResponse.kt
rename to core/data/src/main/java/com/loodos/data/model/login/LoginResponse.kt
index 64b7ccd..d8cf539 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/model/login/LoginResponse.kt
+++ b/core/data/src/main/java/com/loodos/data/model/login/LoginResponse.kt
@@ -1,4 +1,4 @@
-package com.loodos.samplecomposeandroid.core.data.model.login
+package com.loodos.data.model.login
/**
* Created by mertcantoptas on 13.04.2023
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/remote/api/AuthenticationService.kt b/core/data/src/main/java/com/loodos/data/remote/api/AuthenticationService.kt
similarity index 54%
rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/remote/api/AuthenticationService.kt
rename to core/data/src/main/java/com/loodos/data/remote/api/AuthenticationService.kt
index 3c9df17..cc8f1e9 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/remote/api/AuthenticationService.kt
+++ b/core/data/src/main/java/com/loodos/data/remote/api/AuthenticationService.kt
@@ -1,7 +1,7 @@
-package com.loodos.samplecomposeandroid.core.data.remote.api
+package com.loodos.data.remote.api
-import com.loodos.samplecomposeandroid.core.data.model.login.LoginBody
-import com.loodos.samplecomposeandroid.core.data.model.login.LoginResponse
+import com.loodos.data.model.login.LoginBody
+import com.loodos.data.model.login.LoginResponse
import retrofit2.http.Body
import retrofit2.http.POST
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/remote/source/AuthenticationRemoteDataSource.kt b/core/data/src/main/java/com/loodos/data/remote/source/AuthenticationRemoteDataSource.kt
similarity index 56%
rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/remote/source/AuthenticationRemoteDataSource.kt
rename to core/data/src/main/java/com/loodos/data/remote/source/AuthenticationRemoteDataSource.kt
index 5b11a37..6cff1a7 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/remote/source/AuthenticationRemoteDataSource.kt
+++ b/core/data/src/main/java/com/loodos/data/remote/source/AuthenticationRemoteDataSource.kt
@@ -1,6 +1,6 @@
-package com.loodos.samplecomposeandroid.core.data.remote.source
+package com.loodos.data.remote.source
-import com.loodos.samplecomposeandroid.core.data.model.login.LoginResponse
+import com.loodos.data.model.login.LoginResponse
/**
* Created by mertcantoptas on 13.04.2023
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/remote/source/AuthenticationRemoteDataSourceImpl.kt b/core/data/src/main/java/com/loodos/data/remote/source/AuthenticationRemoteDataSourceImpl.kt
similarity index 57%
rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/remote/source/AuthenticationRemoteDataSourceImpl.kt
rename to core/data/src/main/java/com/loodos/data/remote/source/AuthenticationRemoteDataSourceImpl.kt
index 597efc3..0f0f4c4 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/remote/source/AuthenticationRemoteDataSourceImpl.kt
+++ b/core/data/src/main/java/com/loodos/data/remote/source/AuthenticationRemoteDataSourceImpl.kt
@@ -1,8 +1,8 @@
-package com.loodos.samplecomposeandroid.core.data.remote.source
+package com.loodos.data.remote.source
-import com.loodos.samplecomposeandroid.core.data.model.login.LoginBody
-import com.loodos.samplecomposeandroid.core.data.model.login.LoginResponse
-import com.loodos.samplecomposeandroid.core.data.remote.api.AuthenticationService
+import com.loodos.data.model.login.LoginBody
+import com.loodos.data.model.login.LoginResponse
+import com.loodos.data.remote.api.AuthenticationService
import javax.inject.Inject
class AuthenticationRemoteDataSourceImpl @Inject constructor(
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/repository/AuthenticationRepository.kt b/core/data/src/main/java/com/loodos/data/repository/AuthenticationRepository.kt
similarity index 55%
rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/repository/AuthenticationRepository.kt
rename to core/data/src/main/java/com/loodos/data/repository/AuthenticationRepository.kt
index 993897a..8be8764 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/repository/AuthenticationRepository.kt
+++ b/core/data/src/main/java/com/loodos/data/repository/AuthenticationRepository.kt
@@ -1,6 +1,6 @@
-package com.loodos.samplecomposeandroid.core.data.repository
+package com.loodos.data.repository
-import com.loodos.samplecomposeandroid.core.data.model.login.LoginResponse
+import com.loodos.data.model.login.LoginResponse
/**
* Created by mertcantoptas on 13.04.2023
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/repository/AuthenticationRepositoryImpl.kt b/core/data/src/main/java/com/loodos/data/repository/AuthenticationRepositoryImpl.kt
similarity index 61%
rename from app/src/main/java/com/loodos/samplecomposeandroid/core/data/repository/AuthenticationRepositoryImpl.kt
rename to core/data/src/main/java/com/loodos/data/repository/AuthenticationRepositoryImpl.kt
index 896ba33..ebdd68e 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/core/data/repository/AuthenticationRepositoryImpl.kt
+++ b/core/data/src/main/java/com/loodos/data/repository/AuthenticationRepositoryImpl.kt
@@ -1,7 +1,7 @@
-package com.loodos.samplecomposeandroid.core.data.repository
+package com.loodos.data.repository
-import com.loodos.samplecomposeandroid.core.data.model.login.LoginResponse
-import com.loodos.samplecomposeandroid.core.data.remote.source.AuthenticationRemoteDataSource
+import com.loodos.data.model.login.LoginResponse
+import com.loodos.data.remote.source.AuthenticationRemoteDataSource
import javax.inject.Inject
class AuthenticationRepositoryImpl @Inject constructor(
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/util/ConnectivityManagerNetworkMonitor.kt b/core/data/src/main/java/com/loodos/data/util/ConnectivityManagerNetworkMonitor.kt
similarity index 97%
rename from app/src/main/java/com/loodos/samplecomposeandroid/core/util/ConnectivityManagerNetworkMonitor.kt
rename to core/data/src/main/java/com/loodos/data/util/ConnectivityManagerNetworkMonitor.kt
index 663f1a3..dc33772 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/core/util/ConnectivityManagerNetworkMonitor.kt
+++ b/core/data/src/main/java/com/loodos/data/util/ConnectivityManagerNetworkMonitor.kt
@@ -1,4 +1,4 @@
-package com.loodos.samplecomposeandroid.core.util
+package com.loodos.data.util
import android.content.Context
import android.net.ConnectivityManager
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/util/NetworkMonitor.kt b/core/data/src/main/java/com/loodos/data/util/NetworkMonitor.kt
similarity index 75%
rename from app/src/main/java/com/loodos/samplecomposeandroid/core/util/NetworkMonitor.kt
rename to core/data/src/main/java/com/loodos/data/util/NetworkMonitor.kt
index fa1d9ec..bdd1800 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/core/util/NetworkMonitor.kt
+++ b/core/data/src/main/java/com/loodos/data/util/NetworkMonitor.kt
@@ -1,4 +1,4 @@
-package com.loodos.samplecomposeandroid.core.util
+package com.loodos.data.util
import kotlinx.coroutines.flow.Flow
diff --git a/core/data/src/test/java/com/loodos/data/ExampleUnitTest.kt b/core/data/src/test/java/com/loodos/data/ExampleUnitTest.kt
new file mode 100644
index 0000000..d148c91
--- /dev/null
+++ b/core/data/src/test/java/com/loodos/data/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.loodos.data
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * 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)
+ }
+}
diff --git a/core/designsystem/.gitignore b/core/designsystem/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/core/designsystem/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/core/designsystem/build.gradle.kts b/core/designsystem/build.gradle.kts
new file mode 100644
index 0000000..f78c4cf
--- /dev/null
+++ b/core/designsystem/build.gradle.kts
@@ -0,0 +1,27 @@
+plugins {
+ id("samplecomposeanroid.android.library")
+ id("samplecomposeanroid.android.library.compose")
+}
+
+android {
+ defaultConfig {
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+ namespace = "com.loodos.samplecomposeanroid.core.designsystem"
+}
+
+dependencies {
+ api(libs.androidx.compose.foundation)
+ api(libs.androidx.compose.foundation.layout)
+ api(libs.androidx.compose.material.iconsExtended)
+ api(libs.androidx.compose.material3)
+ api(libs.androidx.compose.runtime)
+ api(libs.androidx.compose.ui.tooling.preview)
+ api(libs.androidx.compose.ui.util)
+
+ debugApi(libs.androidx.compose.ui.tooling)
+
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.coil.kt.compose)
+
+}
diff --git a/core/designsystem/consumer-rules.pro b/core/designsystem/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
diff --git a/core/designsystem/proguard-rules.pro b/core/designsystem/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/core/designsystem/proguard-rules.pro
@@ -0,0 +1,21 @@
+# 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/core/designsystem/src/androidTest/java/com/loodos/designsystems/ExampleInstrumentedTest.kt b/core/designsystem/src/androidTest/java/com/loodos/designsystems/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..3d74044
--- /dev/null
+++ b/core/designsystem/src/androidTest/java/com/loodos/designsystems/ExampleInstrumentedTest.kt
@@ -0,0 +1,25 @@
+package com.loodos.designsystems
+
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.ext.junit.runners.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("com.merttoptas.designsystems.test", appContext.packageName)
+ }
+}
+
diff --git a/core/designsystem/src/main/AndroidManifest.xml b/core/designsystem/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..a5918e6
--- /dev/null
+++ b/core/designsystem/src/main/AndroidManifest.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/designsystem/Animations.kt b/core/designsystem/src/main/java/com/loodos/designsystems/animation/Animations.kt
similarity index 90%
rename from app/src/main/java/com/loodos/samplecomposeandroid/core/designsystem/Animations.kt
rename to core/designsystem/src/main/java/com/loodos/designsystems/animation/Animations.kt
index 3a6ab30..68b03d3 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/core/designsystem/Animations.kt
+++ b/core/designsystem/src/main/java/com/loodos/designsystems/animation/Animations.kt
@@ -1,4 +1,4 @@
-package com.loodos.samplecomposeandroid.core.designsystem
+package com.loodos.designsystems.animation
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/ui/components/CustomTextField.kt b/core/designsystem/src/main/java/com/loodos/designsystems/component/CustomTextField.kt
similarity index 75%
rename from app/src/main/java/com/loodos/samplecomposeandroid/ui/components/CustomTextField.kt
rename to core/designsystem/src/main/java/com/loodos/designsystems/component/CustomTextField.kt
index 475a6df..326f231 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/ui/components/CustomTextField.kt
+++ b/core/designsystem/src/main/java/com/loodos/designsystems/component/CustomTextField.kt
@@ -1,27 +1,18 @@
-@file:OptIn(ExperimentalMaterial3Api::class)
+package com.loodos.designsystems.component
-package com.loodos.samplecomposeandroid.ui.components
-
-import androidx.compose.foundation.Image
-import androidx.compose.foundation.layout.size
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
-import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.OutlinedTextField
+import androidx.compose.material3.OutlinedTextFieldDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldColors
-import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.vector.ImageVector
-import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.dp
-import com.loodos.samplecomposeandroid.R
/**
* Created by mertcantoptas on 10.05.2023
@@ -33,7 +24,7 @@ fun CustomTextField(
label: @Composable (() -> Unit),
onValueChange: (String) -> Unit,
modifier: Modifier = Modifier,
- colors: TextFieldColors = TextFieldDefaults.outlinedTextFieldColors(),
+ colors: TextFieldColors = OutlinedTextFieldDefaults.colors(),
enabled: Boolean = true,
trailingIcon: @Composable (() -> Unit)? = null,
placeholder: @Composable (() -> Unit)? = null,
@@ -82,13 +73,7 @@ private fun CustomTextFieldFillTextPreview() {
label = { Text(text = "Label") },
placeholder = { Text(text = "Placeholder") },
isError = true,
- trailingIcon = {
- Image(
- modifier = Modifier.size(24.dp),
- imageVector = ImageVector.vectorResource(id = R.drawable.ic_cancel),
- contentDescription = "",
- )
- },
+ trailingIcon = {},
supportingText = { Text(text = "Supporting Text") },
)
}
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/ui/components/MainAppScaffold.kt b/core/designsystem/src/main/java/com/loodos/designsystems/component/MainAppScaffold.kt
similarity index 92%
rename from app/src/main/java/com/loodos/samplecomposeandroid/ui/components/MainAppScaffold.kt
rename to core/designsystem/src/main/java/com/loodos/designsystems/component/MainAppScaffold.kt
index be8879b..19f257e 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/ui/components/MainAppScaffold.kt
+++ b/core/designsystem/src/main/java/com/loodos/designsystems/component/MainAppScaffold.kt
@@ -1,4 +1,4 @@
-package com.loodos.samplecomposeandroid.ui.components
+package com.loodos.designsystems.component
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.imePadding
@@ -12,10 +12,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-/**
- * Created by mertcantoptas on 10.03.2023
- */
-
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainAppScaffold(
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/designsystem/icon/AppIcons.kt b/core/designsystem/src/main/java/com/loodos/designsystems/icon/AppIcons.kt
similarity index 86%
rename from app/src/main/java/com/loodos/samplecomposeandroid/core/designsystem/icon/AppIcons.kt
rename to core/designsystem/src/main/java/com/loodos/designsystems/icon/AppIcons.kt
index 55252c8..348e914 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/core/designsystem/icon/AppIcons.kt
+++ b/core/designsystem/src/main/java/com/loodos/designsystems/icon/AppIcons.kt
@@ -1,4 +1,4 @@
-package com.loodos.samplecomposeandroid.core.designsystem.icon
+package com.loodos.designsystems.icon
import androidx.annotation.DrawableRes
import androidx.compose.material.icons.Icons
@@ -11,6 +11,9 @@ import androidx.compose.material.icons.outlined.Person
import androidx.compose.runtime.Stable
import androidx.compose.ui.graphics.vector.ImageVector
+/**
+ * Loodos Sample App in Android icons. Material icons are [ImageVector]s, custom icons are drawable resource IDs.
+ */
object AppIcons {
val Home = Icons.Default.Home
val HomeOutlined = Icons.Outlined.Home
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/ui/theme/Color.kt b/core/designsystem/src/main/java/com/loodos/designsystems/theme/Color.kt
similarity index 67%
rename from app/src/main/java/com/loodos/samplecomposeandroid/ui/theme/Color.kt
rename to core/designsystem/src/main/java/com/loodos/designsystems/theme/Color.kt
index 85d4c6a..fabd2be 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/ui/theme/Color.kt
+++ b/core/designsystem/src/main/java/com/loodos/designsystems/theme/Color.kt
@@ -1,7 +1,11 @@
-package com.loodos.samplecomposeandroid.ui.theme
+package com.loodos.designsystems.theme
import androidx.compose.ui.graphics.Color
+/**
+ * Loodos Sample App in Android colors. All colors must be defined here
+ */
+
val Purple80 = Color(0xFFD0BCFF)
val PurpleGrey80 = Color(0xFFCCC2DC)
val Pink80 = Color(0xFFEFB8C8)
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/ui/theme/Theme.kt b/core/designsystem/src/main/java/com/loodos/designsystems/theme/Theme.kt
similarity index 95%
rename from app/src/main/java/com/loodos/samplecomposeandroid/ui/theme/Theme.kt
rename to core/designsystem/src/main/java/com/loodos/designsystems/theme/Theme.kt
index b2fa5a2..780541e 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/ui/theme/Theme.kt
+++ b/core/designsystem/src/main/java/com/loodos/designsystems/theme/Theme.kt
@@ -1,4 +1,4 @@
-package com.loodos.samplecomposeandroid.ui.theme
+package com.loodos.designsystems.theme
import android.app.Activity
import android.os.Build
@@ -22,6 +22,9 @@ private val DarkColorScheme = darkColorScheme(
tertiary = Pink80,
)
+/**
+ * Light default theme color scheme
+ */
private val LightColorScheme = lightColorScheme(
primary = Purple40,
secondary = PurpleGrey40,
@@ -45,6 +48,7 @@ fun SampleComposeAndroidTheme(
dynamicColor: Boolean = true,
content: @Composable () -> Unit,
) {
+ // Color scheme
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/ui/theme/Type.kt b/core/designsystem/src/main/java/com/loodos/designsystems/theme/Type.kt
similarity index 95%
rename from app/src/main/java/com/loodos/samplecomposeandroid/ui/theme/Type.kt
rename to core/designsystem/src/main/java/com/loodos/designsystems/theme/Type.kt
index 79e8797..7672eaa 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/ui/theme/Type.kt
+++ b/core/designsystem/src/main/java/com/loodos/designsystems/theme/Type.kt
@@ -1,4 +1,4 @@
-package com.loodos.samplecomposeandroid.ui.theme
+package com.loodos.designsystems.theme
import androidx.compose.material3.Typography
import androidx.compose.ui.text.TextStyle
diff --git a/core/designsystem/src/test/java/com/loodos/designsystems/ExampleUnitTest.kt b/core/designsystem/src/test/java/com/loodos/designsystems/ExampleUnitTest.kt
new file mode 100644
index 0000000..7d197b4
--- /dev/null
+++ b/core/designsystem/src/test/java/com/loodos/designsystems/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.loodos.designsystems
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * 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)
+ }
+}
diff --git a/core/domain/.gitignore b/core/domain/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/core/domain/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/core/domain/build.gradle.kts b/core/domain/build.gradle.kts
new file mode 100644
index 0000000..b18511b
--- /dev/null
+++ b/core/domain/build.gradle.kts
@@ -0,0 +1,25 @@
+@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
+plugins {
+ id("samplecomposeanroid.android.library")
+ id("samplecomposeanroid.android.library.compose")
+ kotlin("kapt")
+}
+
+
+android {
+ namespace = "com.loodos.samplecomposeanroid.core.domain"
+}
+
+dependencies {
+ implementation(libs.hilt.android)
+ implementation(libs.kotlinx.coroutines.android)
+ implementation(libs.kotlinx.datetime)
+ api(libs.androidx.compose.runtime)
+ api(libs.androidx.compose.runtime.livedata)
+
+ implementation(projects.core.data)
+ implementation(projects.core.common)
+
+ kapt(libs.hilt.compiler)
+
+}
\ No newline at end of file
diff --git a/core/domain/consumer-rules.pro b/core/domain/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
diff --git a/core/domain/proguard-rules.pro b/core/domain/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/core/domain/proguard-rules.pro
@@ -0,0 +1,21 @@
+# 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/core/domain/src/main/AndroidManifest.xml b/core/domain/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..a5918e6
--- /dev/null
+++ b/core/domain/src/main/AndroidManifest.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/domain/LoginExceptions.kt b/core/domain/src/main/java/com/loodos/domain/LoginExceptions.kt
similarity index 100%
rename from app/src/main/java/com/loodos/samplecomposeandroid/core/domain/LoginExceptions.kt
rename to core/domain/src/main/java/com/loodos/domain/LoginExceptions.kt
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/domain/login/LoginResult.kt b/core/domain/src/main/java/com/loodos/domain/login/LoginResult.kt
similarity index 50%
rename from app/src/main/java/com/loodos/samplecomposeandroid/core/domain/login/LoginResult.kt
rename to core/domain/src/main/java/com/loodos/domain/login/LoginResult.kt
index 9f1e793..313b70f 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/core/domain/login/LoginResult.kt
+++ b/core/domain/src/main/java/com/loodos/domain/login/LoginResult.kt
@@ -1,6 +1,7 @@
-package com.loodos.samplecomposeandroid.core.domain.login
+package com.loodos.domain.login
+
+import com.loodos.data.model.login.LoginResponse
-import com.loodos.samplecomposeandroid.core.data.model.login.LoginResponse
data class LoginResult(
val token: String = "",
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/domain/login/LoginUseCase.kt b/core/domain/src/main/java/com/loodos/domain/login/LoginUseCase.kt
similarity index 79%
rename from app/src/main/java/com/loodos/samplecomposeandroid/core/domain/login/LoginUseCase.kt
rename to core/domain/src/main/java/com/loodos/domain/login/LoginUseCase.kt
index 2047ae9..4d42f2c 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/core/domain/login/LoginUseCase.kt
+++ b/core/domain/src/main/java/com/loodos/domain/login/LoginUseCase.kt
@@ -1,6 +1,6 @@
-package com.loodos.samplecomposeandroid.core.domain.login
+package com.loodos.domain.login
-import com.loodos.samplecomposeandroid.core.data.repository.AuthenticationRepository
+import com.loodos.data.repository.AuthenticationRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import javax.inject.Inject
diff --git a/app/src/main/java/com/loodos/samplecomposeandroid/core/domain/login/ValidateAuthUseCase.kt b/core/domain/src/main/java/com/loodos/domain/login/ValidateAuthUseCase.kt
similarity index 86%
rename from app/src/main/java/com/loodos/samplecomposeandroid/core/domain/login/ValidateAuthUseCase.kt
rename to core/domain/src/main/java/com/loodos/domain/login/ValidateAuthUseCase.kt
index 3eb69f2..81b56c0 100644
--- a/app/src/main/java/com/loodos/samplecomposeandroid/core/domain/login/ValidateAuthUseCase.kt
+++ b/core/domain/src/main/java/com/loodos/domain/login/ValidateAuthUseCase.kt
@@ -1,11 +1,11 @@
-package com.loodos.samplecomposeandroid.core.domain.login
+package com.loodos.domain.login
-import com.loodos.samplecomposeandroid.core.common.Resource
-import com.loodos.samplecomposeandroid.core.common.asResource
import com.loodos.samplecomposeandroid.core.domain.PasswordLengthException
import com.loodos.samplecomposeandroid.core.domain.PasswordRequiredException
import com.loodos.samplecomposeandroid.core.domain.UsernameLengthException
import com.loodos.samplecomposeandroid.core.domain.UsernameRequiredException
+import com.loodos.common.result.Resource
+import com.loodos.common.result.asResource
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import javax.inject.Inject
diff --git a/core/domain/src/test/java/com/loodos/domain/ExampleUnitTest.kt b/core/domain/src/test/java/com/loodos/domain/ExampleUnitTest.kt
new file mode 100644
index 0000000..d7354fe
--- /dev/null
+++ b/core/domain/src/test/java/com/loodos/domain/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.loodos.domain
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * 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)
+ }
+}
diff --git a/core/ui/.gitignore b/core/ui/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/core/ui/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts
new file mode 100644
index 0000000..270bf0e
--- /dev/null
+++ b/core/ui/build.gradle.kts
@@ -0,0 +1,31 @@
+plugins {
+ id("samplecomposeanroid.android.library")
+ id("samplecomposeanroid.android.library.compose")
+
+}
+
+android {
+ defaultConfig {
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ }
+ namespace = "com.loodos.samplecomposeanroid.core.ui"
+}
+
+dependencies {
+ api(libs.androidx.compose.foundation)
+ api(libs.androidx.compose.foundation.layout)
+ api(libs.androidx.compose.material.iconsExtended)
+ api(libs.androidx.compose.material3)
+ api(libs.androidx.compose.runtime)
+ api(libs.androidx.compose.runtime.livedata)
+ api(libs.androidx.compose.ui.tooling.preview)
+ api(libs.androidx.compose.ui.util)
+ api(libs.androidx.metrics)
+
+ debugApi(libs.androidx.compose.ui.tooling)
+
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.coil.kt)
+ implementation(libs.coil.kt.compose)
+ implementation(libs.kotlinx.datetime)
+}
\ No newline at end of file
diff --git a/core/ui/proguard-rules.pro b/core/ui/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/core/ui/proguard-rules.pro
@@ -0,0 +1,21 @@
+# 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/core/ui/src/androidTest/java/com/loodos/ui/ExampleInstrumentedTest.kt b/core/ui/src/androidTest/java/com/loodos/ui/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000..c24be3a
--- /dev/null
+++ b/core/ui/src/androidTest/java/com/loodos/ui/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.loodos.ui
+
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.ext.junit.runners.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("com.merttoptas.ui", appContext.packageName)
+ }
+}
diff --git a/core/ui/src/main/AndroidManifest.xml b/core/ui/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..b93358b
--- /dev/null
+++ b/core/ui/src/main/AndroidManifest.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/ui/src/main/res/values/colors.xml b/core/ui/src/main/res/values/colors.xml
new file mode 100644
index 0000000..f8c6127
--- /dev/null
+++ b/core/ui/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/core/ui/src/main/res/values/strings.xml b/core/ui/src/main/res/values/strings.xml
new file mode 100644
index 0000000..e5f8fdc
--- /dev/null
+++ b/core/ui/src/main/res/values/strings.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/core/ui/src/test/java/com/loodos/ui/ExampleUnitTest.kt b/core/ui/src/test/java/com/loodos/ui/ExampleUnitTest.kt
new file mode 100644
index 0000000..994dd10
--- /dev/null
+++ b/core/ui/src/test/java/com/loodos/ui/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.loodos.ui
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * 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)
+ }
+}
diff --git a/gradle.properties b/gradle.properties
index 3c5031e..c69b90e 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -20,4 +20,16 @@ kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# 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
\ No newline at end of file
+android.nonTransitiveRClass=true
+# Automatically convert third-party libraries to use AndroidX
+android.enableJetifier=true
+android.defaults.buildfeatures.resvalues=false
+android.defaults.buildfeatures.shaders=false
+android.features.buildConfig = true
+android.suppressUnsupportedCompileSdk=34
+android.defaults.buildfeatures.buildconfig=true
+
+
+
+
+
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 66809fe..89f14a2 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,79 +1,136 @@
[versions]
-androidxCore = "1.10.1"
-androidxTestCore = "1.5.0"
-androidxLifecycle = "2.6.1"
-androidGradlePlugin = "8.0.0"
-androidxActivity = "1.7.1"
+accompanist = "0.30.1"
+appCompat = "1.6.1"
+androidDesugarJdkLibs = "2.0.3"
+androidGradlePlugin = "8.0.2"
+androidxActivity = "1.8.0"
+navigationCompose = "2.7.4"
+fragmentKtx = "1.6.1"
+okhttp = "4.10.0"
+kotlinxSerializationJson = "1.5.1"
+kotlinxCoroutines = "1.6.4"
+androidxComposeBom = "2023.10.00"
androidxCoreSplashscreen = "1.0.1"
-androidxTestExt = "1.1.5"
-androidxNavigation = "2.5.3"
-androidxEspresso = "3.5.1"
-androidxComposeBom = "2023.05.01"
-chucker = "3.5.2"
-hilt = "2.46.1"
-hiltPlugin = "2.44.2"
+androidxDataStore = "1.0.0"
+androidxMetrics = "1.0.0-alpha04"
+androidxEspresso = "3.5.0"
+androidxHiltNavigationCompose = "1.0.0"
+androidxLifecycle = "2.6.2"
+androidxTest = "1.1.5"
+firebaseBom = "31.2.0"
+firebaseCrashlyticsPlugin = "2.9.4"
+kotlin = "1.8.21"
+gmsPlugin = "4.4.0"
+composeStateEvents = "1.2.3"
+kotlinxDatetime = "0.4.0"
+ksp = "1.8.21-1.0.11"
+coil = "2.2.2"
+dagger = "2.45"
+com-android-test = "8.0.0"
+compileSdk = "34"
+composeCompiler = "1.4.7"
detektGradlePlugin = "1.22.0"
-kotlinterGradlePlugin = "3.14.0"
+espresso = "3.5.1"
+gradleVersionsPlugin = "0.46.0"
hiltNavigationCompose = "1.0.0"
-composeLintChecks = "1.2.0"
-composeStateEvents = "1.2.3"
-turbine = "0.12.1"
-truth = "1.1.3"
-junit4 = "4.13.2"
-truthExt = "1.5.0"
-kotlinTest = "1.8.21"
-kotlin = "1.8.21"
+androidxNavigation = "2.7.4"
+hilt = "2.47"
+junit = "4.13.2"
+kotlinter = "3.14.0"
+ktxCore = "1.12.0"
+leakCanary = "2.10"
+lifecycle = "2.6.2"
+material = "1.10.0"
+minSdk = "21"
+targetSdk = "34"
+moshi = "1.15.0"
retrofit = "2.9.0"
-okhttp = "4.10.0"
-appcompat = "1.6.1"
-material = "1.9.0"
+room = "2.5.1"
+chucker = "3.5.2"
+firebase-pref = "1.4.1"
+secrets = "2.0.1"
+
[libraries]
-androidx-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "androidxCore" }
-androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "androidxComposeBom" }
-androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidxActivity" }
androidx-core-splashscreen = { group = "androidx.core", name = "core-splashscreen", version.ref = "androidxCoreSplashscreen" }
-androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "androidxLifecycle" }
+accompanist-systemuicontroller = { group = "com.google.accompanist", name = "accompanist-systemuicontroller", version.ref = "accompanist" }
+android-desugarJdkLibs = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "androidDesugarJdkLibs" }
+android-material = { group = "com.google.android.material", name = "material", version.ref = "material" }
+androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "androidxActivity" }
+androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "ktxCore" }
+androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appCompat" }
+androidx-fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref = "fragmentKtx" }
+androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle" }
+androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" }
+androidx-room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
+androidx-room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" }
+androidx-room-paging = { group = "androidx.room", name = "room-paging", version.ref = "room" }
+androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation" }
+androidx-compose-runtime = { group = "androidx.compose.runtime", name = "runtime" }
+androidx-compose-runtime-livedata = { group = "androidx.compose.runtime", name = "runtime-livedata" }
+androidx-compose-foundation-layout = { group = "androidx.compose.foundation", name = "foundation-layout" }
+androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
+androidx-compose-material3-windowSizeClass = { group = "androidx.compose.material3", name = "material3-window-size-class" }
androidx-lifecycle-runtimeCompose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "androidxLifecycle" }
-androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
-androidx-compose-ui-testManifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
-androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
+kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "kotlinxCoroutines" }
+androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" }
+androidx-metrics = { group = "androidx.metrics", name = "metrics-performance", version.ref = "androidxMetrics" }
+androidx-room-testing = { group = "androidx.room", name = "room-testing", version.ref = "room" }
+androidx-test-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso" }
+androidx-test-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidxTest" }
+compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "androidxComposeBom" }
androidx-compose-material-iconsExtended = { group = "androidx.compose.material", name = "material-icons-extended" }
-androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
-androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" }
-androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
-androidx-navigation-testing = { group = "androidx.navigation", name = "navigation-testing", version.ref = "androidxNavigation" }
-androidx-test-ktx = { group = "androidx.test", name = "core-ktx", version.ref = "androidxTestCore" }
-androidx-test-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "androidxEspresso" }
-androidx-test-ext-ktx = { group = "androidx.test.ext", name = "junit-ktx", version.ref = "androidxTestExt" }
-androidx-test-ext = { group = "androidx.test.ext", name = "junit", version.ref = "androidxTestExt" }
-androidx-compose-ui-test = { group = "androidx.compose.ui", name = "ui-test-junit4" }
-androidx-test-core = { group = "androidx.test", name = "core", version.ref = "androidxTestCore" }
+compose-material = { group = "androidx.compose.material3", name = "material3" }
+compose-ui = { group = "androidx.compose.ui", name = "ui" }
+compose-ui-test-junit = { group = "androidx.compose.ui", name = "ui-test-junit4" }
+compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
chucker = { group = "com.github.chuckerteam.chucker", name = "library", version.ref = "chucker" }
chucker-no-op = { group = "com.github.chuckerteam.chucker", name = "library-no-op", version.ref = "chucker" }
-hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
-hilt-android-testing = { group = "com.google.dagger", name = "hilt-android-testing", version.ref = "hilt" }
-hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" }
-lint-checks = { group = "com.slack.lint.compose", name = "compose-lint-checks", version.ref = "composeLintChecks" }
-retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
+compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
+kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
+androidx-navigation-testing = { group = "androidx.navigation", name = "navigation-testing", version.ref = "androidxNavigation" }
+androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
retrofit-converter-gson = { group = "com.squareup.retrofit2", name = "converter-gson", version.ref = "retrofit" }
-okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }
+compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
+androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
+androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
+androidx-compose-ui-util = { group = "androidx.compose.ui", name = "ui-util" }
okhttp-logging-interceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" }
+compose-ui-util = { group = "androidx.compose.ui", name = "ui-util" }
+dependency-versions-plugin = { module = "com.github.ben-manes:gradle-versions-plugin", version.ref = "gradleVersionsPlugin" }
+hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
+hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt" }
+hilt-android-testing = { module = "com.google.dagger:hilt-android-testing", version.ref = "hilt" }
+hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" }
+junit4 = { module = "junit:junit", version.ref = "junit" }
+kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinxDatetime" }
+coil-kt = { group = "io.coil-kt", name = "coil", version.ref = "coil" }
+coil-kt-compose = { group = "io.coil-kt", name = "coil-compose", version.ref = "coil" }
+coil-kt-svg = { group = "io.coil-kt", name = "coil-svg", version.ref = "coil" }
+square-leakcanary = { module = "com.squareup.leakcanary:leakcanary-android", version.ref = "leakCanary" }
+square-moshi-kotlin = { module = "com.squareup.moshi:moshi-kotlin", version.ref = "moshi" }
+square-moshi-kotlin-codegen = { module = "com.squareup.moshi:moshi-kotlin-codegen", version.ref = "moshi" }
+square-retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
+square-retrofit-converter-moshi = { module = "com.squareup.retrofit2:converter-moshi", version.ref = "retrofit" }
compose-state-events = { group = "com.github.leonard-palm", name = "compose-state-events", version.ref = "composeStateEvents" }
-turbine = { group = "app.cash.turbine", name = "turbine", version.ref = "turbine" }
-truth = { group = "com.google.truth", name = "truth", version.ref = "truth" }
-truth-ext = { group = "androidx.test.ext", name = "truth", version.ref = "truthExt" }
-junit4 = { group = "junit", name = "junit", version.ref = "junit4" }
-jetbrains-kotlin-test = { group = "org.jetbrains.kotlin", name = "kotlin-test", version.ref = "kotlinTest" }
-jetbrains-kotlin-test-junit = { group = "org.jetbrains.kotlin", name = "kotlin-test-junit", version.ref = "kotlinTest" }
-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
-material = { group = "com.google.android.material", name = "material", version.ref = "material" }
+
+# Dependencies of the included build-logic
+android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" }
+kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
+firebase-crashlytics-gradlePlugin = { group = "com.google.firebase", name = "firebase-crashlytics-gradle", version.ref = "firebaseCrashlyticsPlugin" }
+ksp-gradlePlugin = { group = "com.google.devtools.ksp", name = "com.google.devtools.ksp.gradle.plugin", version.ref = "ksp" }
[plugins]
-android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
-android-library = { id = "com.android.library", version.ref = "androidGradlePlugin" }
-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
-kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
-dagger-hilt = { id = "com.google.dagger.hilt.android", version.ref = "hiltPlugin" }
+com-android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
+com-android-library = { id = "com.android.library", version.ref = "androidGradlePlugin" }
+org-jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+dagger-hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "dagger" }
+kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
+google-services = { id = "com.google.gms.google-services", version.ref = "gmsPlugin" }
+firebase-crashlytics = { id = "com.google.firebase.crashlytics", version.ref = "firebaseCrashlyticsPlugin" }
+com-android-test = { id = "com.android.test", version.ref = "com-android-test" }
+gradle-versions = { id = "com.github.ben-manes.versions", version.ref = "gradleVersionsPlugin" }
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detektGradlePlugin" }
-kotlinter = { id = "org.jmailen.kotlinter", version.ref = "kotlinterGradlePlugin" }
\ No newline at end of file
+kotlinter = { id = "org.jmailen.kotlinter", version.ref = "kotlinter" }
+ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
+secrets = { id = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin", version.ref = "secrets" }
diff --git a/secrets.defaults.properties b/secrets.defaults.properties
new file mode 100644
index 0000000..c9e114b
--- /dev/null
+++ b/secrets.defaults.properties
@@ -0,0 +1,4 @@
+## This file provides default values to modules using the secrets-gradle-plugin. It is necessary
+# because the secrets properties file is not under source control so CI builds will fail without
+# default values.
+BACKEND_URL="https://fakestoreapi.com/"
\ No newline at end of file
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 74bf3c2..bf72b70 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,8 +1,10 @@
pluginManagement {
+ includeBuild("build-logic")
repositories {
google()
mavenCentral()
gradlePluginPortal()
+ maven(url = "https://plugins.gradle.org/m2/")
}
}
dependencyResolutionManagement {
@@ -13,5 +15,11 @@ dependencyResolutionManagement {
maven { url = uri("https://jitpack.io") }
}
}
-rootProject.name = "Sample Compose Android"
+rootProject.name = "samplecomposeandroid"
+enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
include(":app")
+include(":core:ui")
+include(":core:common")
+include(":core:data")
+include(":core:designsystem")
+include(":core:domain")