diff --git a/Android/.idea/deploymentTargetSelector.xml b/Android/.idea/deploymentTargetSelector.xml
index b268ef3..fc8303f 100644
--- a/Android/.idea/deploymentTargetSelector.xml
+++ b/Android/.idea/deploymentTargetSelector.xml
@@ -5,6 +5,9 @@
+
+
+
\ No newline at end of file
diff --git a/Android/.idea/gradle.xml b/Android/.idea/gradle.xml
index 0897082..606ee67 100644
--- a/Android/.idea/gradle.xml
+++ b/Android/.idea/gradle.xml
@@ -10,6 +10,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Android/app/build.gradle.kts b/Android/app/build.gradle.kts
index 056eee6..79c4990 100644
--- a/Android/app/build.gradle.kts
+++ b/Android/app/build.gradle.kts
@@ -53,6 +53,9 @@ android {
dependencies {
+ // feature
+ implementation(project(":feature:main"))
+ implementation(project(":feature:reciperecommend"))
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
diff --git a/Android/app/src/main/AndroidManifest.xml b/Android/app/src/main/AndroidManifest.xml
index 941264a..c9b9cdd 100644
--- a/Android/app/src/main/AndroidManifest.xml
+++ b/Android/app/src/main/AndroidManifest.xml
@@ -15,17 +15,6 @@
android:supportsRtl="true"
android:theme="@style/Theme.Banchango"
tools:targetApi="34">
-
-
-
-
-
-
-
diff --git a/Android/app/src/main/java/com/sundaegukbap/banchango/repository/RecipeRepository.kt b/Android/app/src/main/java/com/sundaegukbap/banchango/repository/RecipeRepository.kt
deleted file mode 100644
index c1769e4..0000000
--- a/Android/app/src/main/java/com/sundaegukbap/banchango/repository/RecipeRepository.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.sundaegukbap.banchango.repository
-
-import com.sundaegukbap.banchango.model.Recipe
-
-interface RecipeRepository {
- fun getRecipeRecommendation(): List
-}
diff --git a/Android/app/src/main/res/values/strings.xml b/Android/app/src/main/res/values/strings.xml
index bcd8b96..f2f388f 100644
--- a/Android/app/src/main/res/values/strings.xml
+++ b/Android/app/src/main/res/values/strings.xml
@@ -1,3 +1,4 @@
banchango
-
\ No newline at end of file
+ Module Title
+
diff --git a/Android/build.gradle.kts b/Android/build.gradle.kts
index fe46b1c..0eda446 100644
--- a/Android/build.gradle.kts
+++ b/Android/build.gradle.kts
@@ -5,6 +5,9 @@ plugins {
alias(libs.plugins.org.jetbrains.kotlin.kapt) apply false
alias(libs.plugins.hilt) apply false
alias(libs.plugins.ktlint) apply true
+ alias(libs.plugins.jetbrains.kotlin.jvm) apply false
+ alias(libs.plugins.android.library) apply false
+ alias(libs.plugins.kotlin.serialization) apply true
}
buildscript {
diff --git a/Android/core/data-api/.gitignore b/Android/core/data-api/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/Android/core/data-api/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Android/core/data-api/build.gradle.kts b/Android/core/data-api/build.gradle.kts
new file mode 100644
index 0000000..2d9b08b
--- /dev/null
+++ b/Android/core/data-api/build.gradle.kts
@@ -0,0 +1,43 @@
+plugins {
+ alias(libs.plugins.android.library)
+ alias(libs.plugins.jetbrains.kotlin.android)
+}
+
+android {
+ namespace = "com.sundaegukbap.banchango.core.data.repository.api"
+ compileSdk = 34
+
+ defaultConfig {
+ minSdk = 28
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles("consumer-rules.pro")
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ }
+ kotlinOptions {
+ jvmTarget = "17"
+ }
+}
+
+dependencies {
+ implementation(project(":core:model"))
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.appcompat)
+ implementation(libs.material)
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+}
diff --git a/Android/core/data-api/consumer-rules.pro b/Android/core/data-api/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
diff --git a/Android/core/data-api/proguard-rules.pro b/Android/core/data-api/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/Android/core/data-api/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/Android/core/data-api/src/main/AndroidManifest.xml b/Android/core/data-api/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..8072ee0
--- /dev/null
+++ b/Android/core/data-api/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/Android/core/data-api/src/main/java/com/sundaegukbap/banchango/core/data/repository/api/RecipeRepository.kt b/Android/core/data-api/src/main/java/com/sundaegukbap/banchango/core/data/repository/api/RecipeRepository.kt
new file mode 100644
index 0000000..945b435
--- /dev/null
+++ b/Android/core/data-api/src/main/java/com/sundaegukbap/banchango/core/data/repository/api/RecipeRepository.kt
@@ -0,0 +1,7 @@
+package com.sundaegukbap.banchango.core.data.repository.api
+
+import com.sundaegukbap.banchango.Recipe
+
+interface RecipeRepository {
+ fun getRecipeRecommendation(): List
+}
diff --git a/Android/core/data-api/src/test/java/com/sundaegukbap/banchango/core/data/repository/api/.gitkeep b/Android/core/data-api/src/test/java/com/sundaegukbap/banchango/core/data/repository/api/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/Android/core/designsystem/.gitignore b/Android/core/designsystem/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/Android/core/designsystem/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Android/core/designsystem/build.gradle.kts b/Android/core/designsystem/build.gradle.kts
new file mode 100644
index 0000000..c7a42da
--- /dev/null
+++ b/Android/core/designsystem/build.gradle.kts
@@ -0,0 +1,55 @@
+plugins {
+ alias(libs.plugins.android.library)
+ alias(libs.plugins.jetbrains.kotlin.android)
+ alias(libs.plugins.org.jetbrains.kotlin.kapt)
+}
+
+android {
+ namespace = "com.sundaegukbap.banchango.core"
+ compileSdk = 34
+
+ defaultConfig {
+ minSdk = 28
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles("consumer-rules.pro")
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ }
+ kotlinOptions {
+ jvmTarget = "17"
+ }
+ buildFeatures {
+ compose = true
+ }
+ composeOptions {
+ kotlinCompilerExtensionVersion = "1.5.1"
+ }
+}
+
+dependencies {
+
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.appcompat)
+ implementation(libs.material)
+ implementation(libs.androidx.material3.android)
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+ implementation(libs.androidx.ui)
+ implementation(libs.androidx.ui.graphics)
+ implementation(libs.androidx.ui.tooling.preview)
+ implementation(libs.glide.compose)
+}
diff --git a/Android/core/designsystem/consumer-rules.pro b/Android/core/designsystem/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
diff --git a/Android/core/designsystem/proguard-rules.pro b/Android/core/designsystem/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/Android/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/Android/core/designsystem/src/androidTest/java/com/sundaegukbap/banchango/core/.gitkeep b/Android/core/designsystem/src/androidTest/java/com/sundaegukbap/banchango/core/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/Android/core/designsystem/src/main/AndroidManifest.xml b/Android/core/designsystem/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..8072ee0
--- /dev/null
+++ b/Android/core/designsystem/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/Android/app/src/main/java/com/sundaegukbap/banchango/core/designsystem/NetworkImage.kt b/Android/core/designsystem/src/main/java/com/sundaegukbap/banchango/core/designsystem/component/NetworkImage.kt
similarity index 67%
rename from Android/app/src/main/java/com/sundaegukbap/banchango/core/designsystem/NetworkImage.kt
rename to Android/core/designsystem/src/main/java/com/sundaegukbap/banchango/core/designsystem/component/NetworkImage.kt
index b2900ef..1fa5959 100644
--- a/Android/app/src/main/java/com/sundaegukbap/banchango/core/designsystem/NetworkImage.kt
+++ b/Android/core/designsystem/src/main/java/com/sundaegukbap/banchango/core/designsystem/component/NetworkImage.kt
@@ -1,4 +1,4 @@
-package com.sundaegukbap.banchango.core.designsystem
+package com.sundaegukbap.banchango.core.designsystem.component
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
@@ -6,9 +6,11 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.tooling.preview.Preview
import com.bumptech.glide.integration.compose.ExperimentalGlideComposeApi
import com.bumptech.glide.integration.compose.GlideImage
import com.bumptech.glide.integration.compose.placeholder
+import com.sundaegukbap.banchango.core.designsystem.theme.BanchangoTheme
@OptIn(ExperimentalGlideComposeApi::class)
@Composable
@@ -23,3 +25,13 @@ fun NetworkImage(modifier: Modifier, url: String) {
)
}
+@Preview(showBackground = true)
+@Composable
+fun PreviewNetworkImage() {
+ BanchangoTheme {
+ NetworkImage(
+ modifier = Modifier.fillMaxSize(),
+ url = "https://www.example.com/image.jpg",
+ )
+ }
+}
diff --git a/Android/app/src/main/java/com/sundaegukbap/banchango/ui/theme/Color.kt b/Android/core/designsystem/src/main/java/com/sundaegukbap/banchango/core/designsystem/theme/Color.kt
similarity index 80%
rename from Android/app/src/main/java/com/sundaegukbap/banchango/ui/theme/Color.kt
rename to Android/core/designsystem/src/main/java/com/sundaegukbap/banchango/core/designsystem/theme/Color.kt
index 12f0b0e..5a18cf7 100644
--- a/Android/app/src/main/java/com/sundaegukbap/banchango/ui/theme/Color.kt
+++ b/Android/core/designsystem/src/main/java/com/sundaegukbap/banchango/core/designsystem/theme/Color.kt
@@ -1,4 +1,4 @@
-package com.sundaegukbap.banchango.ui.theme
+package com.sundaegukbap.banchango.core.designsystem.theme
import androidx.compose.ui.graphics.Color
diff --git a/Android/app/src/main/java/com/sundaegukbap/banchango/ui/theme/Theme.kt b/Android/core/designsystem/src/main/java/com/sundaegukbap/banchango/core/designsystem/theme/Theme.kt
similarity index 94%
rename from Android/app/src/main/java/com/sundaegukbap/banchango/ui/theme/Theme.kt
rename to Android/core/designsystem/src/main/java/com/sundaegukbap/banchango/core/designsystem/theme/Theme.kt
index fe77ab1..5395ba6 100644
--- a/Android/app/src/main/java/com/sundaegukbap/banchango/ui/theme/Theme.kt
+++ b/Android/core/designsystem/src/main/java/com/sundaegukbap/banchango/core/designsystem/theme/Theme.kt
@@ -1,4 +1,4 @@
-package com.sundaegukbap.banchango.ui.theme
+package com.sundaegukbap.banchango.core.designsystem.theme
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
@@ -51,7 +51,7 @@ fun BanchangoTheme(
MaterialTheme(
colorScheme = colorScheme,
+ content = content,
typography = Typography,
- content = content
)
}
diff --git a/Android/app/src/main/java/com/sundaegukbap/banchango/ui/theme/Type.kt b/Android/core/designsystem/src/main/java/com/sundaegukbap/banchango/core/designsystem/theme/Type.kt
similarity index 94%
rename from Android/app/src/main/java/com/sundaegukbap/banchango/ui/theme/Type.kt
rename to Android/core/designsystem/src/main/java/com/sundaegukbap/banchango/core/designsystem/theme/Type.kt
index 66b1766..c21d109 100644
--- a/Android/app/src/main/java/com/sundaegukbap/banchango/ui/theme/Type.kt
+++ b/Android/core/designsystem/src/main/java/com/sundaegukbap/banchango/core/designsystem/theme/Type.kt
@@ -1,4 +1,4 @@
-package com.sundaegukbap.banchango.ui.theme
+package com.sundaegukbap.banchango.core.designsystem.theme
import androidx.compose.material3.Typography
import androidx.compose.ui.text.TextStyle
diff --git a/Android/core/designsystem/src/test/java/com/sundaegukbap/banchango/core/.gitkeep b/Android/core/designsystem/src/test/java/com/sundaegukbap/banchango/core/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/Android/core/domain/.gitignore b/Android/core/domain/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/Android/core/domain/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Android/core/domain/build.gradle.kts b/Android/core/domain/build.gradle.kts
new file mode 100644
index 0000000..793bed4
--- /dev/null
+++ b/Android/core/domain/build.gradle.kts
@@ -0,0 +1,9 @@
+plugins {
+ id("java-library")
+ alias(libs.plugins.jetbrains.kotlin.jvm)
+}
+
+java {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+}
diff --git a/Android/core/domain/src/main/java/com/sundaegukbap/banchango/core/domain/.gitkeep b/Android/core/domain/src/main/java/com/sundaegukbap/banchango/core/domain/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/Android/core/model/.gitignore b/Android/core/model/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/Android/core/model/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Android/core/model/build.gradle.kts b/Android/core/model/build.gradle.kts
new file mode 100644
index 0000000..793bed4
--- /dev/null
+++ b/Android/core/model/build.gradle.kts
@@ -0,0 +1,9 @@
+plugins {
+ id("java-library")
+ alias(libs.plugins.jetbrains.kotlin.jvm)
+}
+
+java {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+}
diff --git a/Android/app/src/main/java/com/sundaegukbap/banchango/model/Recipe.kt b/Android/core/model/src/main/java/com/sundaegukbap/banchango/Recipe.kt
similarity index 86%
rename from Android/app/src/main/java/com/sundaegukbap/banchango/model/Recipe.kt
rename to Android/core/model/src/main/java/com/sundaegukbap/banchango/Recipe.kt
index adb62e5..8822006 100644
--- a/Android/app/src/main/java/com/sundaegukbap/banchango/model/Recipe.kt
+++ b/Android/core/model/src/main/java/com/sundaegukbap/banchango/Recipe.kt
@@ -1,4 +1,4 @@
-package com.sundaegukbap.banchango.model
+package com.sundaegukbap.banchango
data class Recipe(
val id: Long,
diff --git a/Android/core/navigation/.gitignore b/Android/core/navigation/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/Android/core/navigation/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Android/core/navigation/build.gradle.kts b/Android/core/navigation/build.gradle.kts
new file mode 100644
index 0000000..2be778d
--- /dev/null
+++ b/Android/core/navigation/build.gradle.kts
@@ -0,0 +1,45 @@
+plugins {
+ alias(libs.plugins.android.library)
+ alias(libs.plugins.jetbrains.kotlin.android)
+ alias(libs.plugins.kotlin.serialization)
+}
+
+android {
+ namespace = "com.sundaegukbap.banchango.navigation"
+ compileSdk = 34
+
+ defaultConfig {
+ minSdk = 28
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles("consumer-rules.pro")
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ }
+ kotlinOptions {
+ jvmTarget = "17"
+ }
+}
+
+dependencies {
+
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.appcompat)
+ implementation(libs.material)
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+ implementation(libs.kotlinx.serialization.json)
+}
diff --git a/Android/core/navigation/consumer-rules.pro b/Android/core/navigation/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
diff --git a/Android/core/navigation/proguard-rules.pro b/Android/core/navigation/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/Android/core/navigation/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/Android/core/navigation/src/main/AndroidManifest.xml b/Android/core/navigation/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..8072ee0
--- /dev/null
+++ b/Android/core/navigation/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/Android/core/navigation/src/main/java/com/sundaegukbap/banchango/navigation/Route.kt b/Android/core/navigation/src/main/java/com/sundaegukbap/banchango/navigation/Route.kt
new file mode 100644
index 0000000..27a0199
--- /dev/null
+++ b/Android/core/navigation/src/main/java/com/sundaegukbap/banchango/navigation/Route.kt
@@ -0,0 +1,16 @@
+package com.sundaegukbap.banchango.navigation
+
+import kotlinx.serialization.Serializable
+
+sealed interface Route {
+ @Serializable
+ data class RecipeDetail(val recipeId: String) : Route
+}
+
+sealed interface MainTabRoute : Route {
+ @Serializable
+ data object RecipeRecommend : MainTabRoute
+
+ @Serializable
+ data object Home : MainTabRoute
+}
diff --git a/Android/feature/home/.gitignore b/Android/feature/home/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/Android/feature/home/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Android/feature/home/build.gradle.kts b/Android/feature/home/build.gradle.kts
new file mode 100644
index 0000000..44bbac8
--- /dev/null
+++ b/Android/feature/home/build.gradle.kts
@@ -0,0 +1,77 @@
+plugins {
+ alias(libs.plugins.android.library)
+ alias(libs.plugins.jetbrains.kotlin.android)
+ alias(libs.plugins.org.jetbrains.kotlin.kapt)
+ alias(libs.plugins.hilt)
+}
+
+android {
+ namespace = "com.sundaegukbap.banchango.feature.home"
+ compileSdk = 34
+
+ defaultConfig {
+ minSdk = 28
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles("consumer-rules.pro")
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ }
+ kotlinOptions {
+ jvmTarget = "17"
+ }
+ buildFeatures {
+ compose = true
+ }
+ composeOptions {
+ kotlinCompilerExtensionVersion = "1.5.1"
+ }
+}
+
+dependencies {
+ implementation(project(":core:model"))
+ implementation(project(":core:designsystem"))
+ implementation(project(":core:navigation"))
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.lifecycle.runtime.ktx)
+ implementation(libs.androidx.activity.compose)
+ implementation(platform(libs.androidx.compose.bom))
+ implementation(libs.androidx.ui)
+ implementation(libs.androidx.ui.graphics)
+ implementation(libs.androidx.ui.tooling.preview)
+ implementation(libs.androidx.material3)
+ implementation(libs.androidx.lifecycle.runtime.compose.android)
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+ androidTestImplementation(platform(libs.androidx.compose.bom))
+ androidTestImplementation(libs.androidx.ui.test.junit4)
+ debugImplementation(libs.androidx.ui.tooling)
+ debugImplementation(libs.androidx.ui.test.manifest)
+
+ implementation(libs.dagger.hilt.android)
+ kapt(libs.dagger.hilt.compiler)
+ implementation(libs.lifecycle.viewmodel.ktx)
+
+ // navigation
+ implementation(libs.navigation.compose)
+ implementation(libs.hilt.navigation.compose)
+
+ // status bar
+ implementation(libs.accompanist.systemuicontroller)
+
+ // glide
+ implementation(libs.glide.compose)
+}
diff --git a/Android/feature/home/consumer-rules.pro b/Android/feature/home/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
diff --git a/Android/feature/home/proguard-rules.pro b/Android/feature/home/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/Android/feature/home/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/Android/feature/home/src/androidTest/java/com/sundaegukbap/banchango/feature/home/.gitkeep b/Android/feature/home/src/androidTest/java/com/sundaegukbap/banchango/feature/home/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/Android/feature/home/src/main/AndroidManifest.xml b/Android/feature/home/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..8072ee0
--- /dev/null
+++ b/Android/feature/home/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/Android/feature/home/src/main/java/com/sundaegukbap/banchango/feature/home/HomeScreen.kt b/Android/feature/home/src/main/java/com/sundaegukbap/banchango/feature/home/HomeScreen.kt
new file mode 100644
index 0000000..90a166d
--- /dev/null
+++ b/Android/feature/home/src/main/java/com/sundaegukbap/banchango/feature/home/HomeScreen.kt
@@ -0,0 +1,8 @@
+package com.sundaegukbap.banchango.feature.home
+
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.runtime.Composable
+
+@Composable
+fun HomeScreen(padding: PaddingValues) {
+}
diff --git a/Android/feature/home/src/main/java/com/sundaegukbap/banchango/feature/home/navigation/HomeNavigator.kt b/Android/feature/home/src/main/java/com/sundaegukbap/banchango/feature/home/navigation/HomeNavigator.kt
new file mode 100644
index 0000000..e26aeac
--- /dev/null
+++ b/Android/feature/home/src/main/java/com/sundaegukbap/banchango/feature/home/navigation/HomeNavigator.kt
@@ -0,0 +1,19 @@
+package com.sundaegukbap.banchango.feature.home.navigation
+
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.navigation.NavController
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.NavOptions
+import androidx.navigation.compose.composable
+import com.sundaegukbap.banchango.feature.home.HomeScreen
+import com.sundaegukbap.banchango.navigation.MainTabRoute
+
+fun NavController.navigateHome(navOptions: NavOptions) {
+ navigate(MainTabRoute.Home, navOptions)
+}
+
+fun NavGraphBuilder.homeNavGraph(padding: PaddingValues) {
+ composable {
+ HomeScreen(padding)
+ }
+}
diff --git a/Android/feature/home/src/test/java/com/sundaegukbap/banchango/feature/home/.gitkeep b/Android/feature/home/src/test/java/com/sundaegukbap/banchango/feature/home/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/Android/feature/main/.gitignore b/Android/feature/main/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/Android/feature/main/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Android/feature/main/build.gradle.kts b/Android/feature/main/build.gradle.kts
new file mode 100644
index 0000000..bbcb35b
--- /dev/null
+++ b/Android/feature/main/build.gradle.kts
@@ -0,0 +1,83 @@
+plugins {
+ alias(libs.plugins.android.library)
+ alias(libs.plugins.jetbrains.kotlin.android)
+ alias(libs.plugins.org.jetbrains.kotlin.kapt)
+ alias(libs.plugins.hilt)
+}
+
+android {
+ namespace = "com.sundaegukbap.banchango.feature.main"
+ compileSdk = 34
+
+ defaultConfig {
+ minSdk = 28
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles("consumer-rules.pro")
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ }
+ kotlinOptions {
+ jvmTarget = "17"
+ }
+ buildFeatures {
+ compose = true
+ }
+ composeOptions {
+ kotlinCompilerExtensionVersion = "1.5.1"
+ }
+}
+
+dependencies {
+ implementation(project(":core:model"))
+ implementation(project(":core:designsystem"))
+ implementation(project(":core:navigation"))
+ implementation(project(":feature:reciperecommend"))
+ implementation(project(":feature:home"))
+
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.lifecycle.runtime.ktx)
+ implementation(libs.androidx.activity.compose)
+ implementation(platform(libs.androidx.compose.bom))
+ implementation(libs.androidx.ui)
+ implementation(libs.androidx.ui.graphics)
+ implementation(libs.androidx.ui.tooling.preview)
+ implementation(libs.androidx.material3)
+ implementation(libs.androidx.lifecycle.runtime.compose.android)
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+ androidTestImplementation(platform(libs.androidx.compose.bom))
+ androidTestImplementation(libs.androidx.ui.test.junit4)
+ debugImplementation(libs.androidx.ui.tooling)
+ debugImplementation(libs.androidx.ui.test.manifest)
+
+ // hilt
+ implementation(libs.dagger.hilt.android)
+ kapt(libs.dagger.hilt.compiler)
+ implementation(libs.lifecycle.viewmodel.ktx)
+
+ // navigation
+ implementation(libs.navigation.compose)
+ implementation(libs.hilt.navigation.compose)
+
+ // status bar
+ implementation(libs.accompanist.systemuicontroller)
+
+ // glide
+ implementation(libs.glide.compose)
+
+ implementation(libs.kotlinx.immutable)
+}
diff --git a/Android/feature/main/consumer-rules.pro b/Android/feature/main/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
diff --git a/Android/feature/main/proguard-rules.pro b/Android/feature/main/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/Android/feature/main/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/Android/feature/main/src/androidTest/java/com/sundaegukbap/banchango/feature/main/.gitkeep b/Android/feature/main/src/androidTest/java/com/sundaegukbap/banchango/feature/main/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/Android/feature/main/src/main/AndroidManifest.xml b/Android/feature/main/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..8934fd2
--- /dev/null
+++ b/Android/feature/main/src/main/AndroidManifest.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Android/app/src/main/java/com/sundaegukbap/banchango/presentation/reciperecommend/MainActivity.kt b/Android/feature/main/src/main/java/com/sundaegukbap/banchango/feature/main/MainActivity.kt
similarity index 73%
rename from Android/app/src/main/java/com/sundaegukbap/banchango/presentation/reciperecommend/MainActivity.kt
rename to Android/feature/main/src/main/java/com/sundaegukbap/banchango/feature/main/MainActivity.kt
index bfbfe82..48fe228 100644
--- a/Android/app/src/main/java/com/sundaegukbap/banchango/presentation/reciperecommend/MainActivity.kt
+++ b/Android/feature/main/src/main/java/com/sundaegukbap/banchango/feature/main/MainActivity.kt
@@ -1,32 +1,35 @@
-package com.sundaegukbap.banchango.presentation.reciperecommend
+package com.sundaegukbap.banchango.feature.main
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
-import androidx.activity.viewModels
import androidx.compose.ui.graphics.Color
import com.google.accompanist.systemuicontroller.rememberSystemUiController
-import com.sundaegukbap.banchango.ui.theme.BanchangoTheme
+import com.sundaegukbap.banchango.core.designsystem.theme.BanchangoTheme
import dagger.hilt.android.AndroidEntryPoint
+
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
- private val viewModel: RecipeRecommendViewModel by viewModels()
-
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
- viewModel.getRecipeRecommendation()
setContent {
BanchangoTheme {
+ val navController = rememberMainNavigator()
+
val systemUiController = rememberSystemUiController()
systemUiController.setSystemBarsColor(color = Color(0xBFFFFFFF), darkIcons = true)
systemUiController.setNavigationBarColor(
color = Color(0xFFFFFFFF)
)
- RecipesRecommendScreen()
+
+ MainScreen(
+ navigator = navController,
+ onChangeDarkTheme = {}
+ )
}
}
}
diff --git a/Android/feature/main/src/main/java/com/sundaegukbap/banchango/feature/main/MainBottomBar.kt b/Android/feature/main/src/main/java/com/sundaegukbap/banchango/feature/main/MainBottomBar.kt
new file mode 100644
index 0000000..22dc5d4
--- /dev/null
+++ b/Android/feature/main/src/main/java/com/sundaegukbap/banchango/feature/main/MainBottomBar.kt
@@ -0,0 +1,108 @@
+package com.sundaegukbap.banchango.feature.main
+
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import kotlinx.collections.immutable.PersistentList
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.fadeOut
+import androidx.compose.animation.slideIn
+import androidx.compose.animation.slideOut
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.RowScope
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.navigationBarsPadding
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.selection.selectable
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.dp
+
+@Composable
+internal fun MainBottomBar(
+ visible: Boolean,
+ tabs: PersistentList,
+ currentTab: MainTab?,
+ onTabSelected: (MainTab) -> Unit,
+) {
+ AnimatedVisibility(
+ visible = visible,
+ enter = fadeIn() + slideIn { IntOffset(0, it.height) },
+ exit = fadeOut() + slideOut { IntOffset(0, it.height) }
+ ) {
+ Row(
+ modifier = Modifier
+ .navigationBarsPadding()
+ .padding(start = 8.dp, end = 8.dp, bottom = 28.dp)
+ .fillMaxWidth()
+ .height(56.dp)
+ .border(
+ width = 1.dp,
+ color = MaterialTheme.colorScheme.outline,
+ shape = RoundedCornerShape(size = 28.dp)
+ )
+ .background(
+ color = MaterialTheme.colorScheme.surface,
+ shape = RoundedCornerShape(28.dp)
+ )
+ .padding(horizontal = 28.dp),
+ horizontalArrangement = Arrangement.spacedBy(8.dp),
+ ) {
+ tabs.forEach { tab ->
+ MainBottomBarItem(
+ tab = tab,
+ selected = tab == currentTab,
+ onClick = { onTabSelected(tab) },
+ )
+ }
+ }
+ }
+}
+
+@Composable
+private fun RowScope.MainBottomBarItem(
+ tab: MainTab,
+ selected: Boolean,
+ onClick: () -> Unit,
+) {
+ Box(
+ modifier = Modifier
+ .weight(1f)
+ .fillMaxHeight()
+ .selectable(
+ selected = selected,
+ indication = null,
+ role = null,
+ interactionSource = remember { MutableInteractionSource() },
+ onClick = onClick,
+ ),
+ contentAlignment = Alignment.Center,
+ ) {
+ Icon(
+ painter = painterResource(tab.iconResId),
+ contentDescription = tab.contentDescription,
+ tint = if (selected) {
+ Neon01
+ } else {
+ MaterialTheme.colorScheme.outline
+ },
+ modifier = Modifier.size(34.dp),
+ )
+ }
+}
+
+val Neon01 = Color(0xFF49F300)
diff --git a/Android/feature/main/src/main/java/com/sundaegukbap/banchango/feature/main/MainNavigator.kt b/Android/feature/main/src/main/java/com/sundaegukbap/banchango/feature/main/MainNavigator.kt
new file mode 100644
index 0000000..b37cd94
--- /dev/null
+++ b/Android/feature/main/src/main/java/com/sundaegukbap/banchango/feature/main/MainNavigator.kt
@@ -0,0 +1,101 @@
+package com.sundaegukbap.banchango.feature.main
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.navigation.NavDestination
+import androidx.navigation.NavDestination.Companion.hasRoute
+import androidx.navigation.NavGraph.Companion.findStartDestination
+import androidx.navigation.NavHostController
+import androidx.navigation.compose.currentBackStackEntryAsState
+import androidx.navigation.compose.rememberNavController
+import androidx.navigation.navOptions
+import com.sundaegukbap.banchango.feature.home.navigation.navigateHome
+import com.sundaegukbap.banchango.feature.reciperecommend.navigation.navigateRecipeRecommend
+import com.sundaegukbap.banchango.navigation.MainTabRoute
+import com.sundaegukbap.banchango.navigation.Route
+
+internal class MainNavigator(
+ val navController: NavHostController,
+) {
+ private val currentDestination: NavDestination?
+ @Composable get() = navController
+ .currentBackStackEntryAsState().value?.destination
+
+ val startDestination = MainTab.RECIPE_RECOMMEND.route
+
+ val currentTab: MainTab?
+ @Composable get() = MainTab.find { tab ->
+ currentDestination?.hasRoute(tab::class) == true
+ }
+
+ fun navigate(tab: MainTab) {
+ val navOptions = navOptions {
+ popUpTo(navController.graph.findStartDestination().id) {
+ saveState = true
+ }
+ launchSingleTop = true
+ restoreState = true
+ }
+
+ when (tab) {
+ MainTab.RECIPE_RECOMMEND -> navController.navigateRecipeRecommend(navOptions)
+ MainTab.HOME -> navController.navigateHome(navOptions)
+ }
+ }
+
+ private fun popBackStack() {
+ navController.popBackStack()
+ }
+
+ fun popBackStackIfNotHome() {
+ if (!isSameCurrentDestination()) {
+ popBackStack()
+ }
+ }
+
+ private inline fun isSameCurrentDestination(): Boolean {
+ return navController.currentDestination?.hasRoute() == true
+ }
+
+ @Composable
+ fun shouldShowBottomBar() = MainTab.contains {
+ currentDestination?.hasRoute(it::class) == true
+ }
+}
+
+@Composable
+internal fun rememberMainNavigator(
+ navController: NavHostController = rememberNavController(),
+): MainNavigator = remember(navController) {
+ MainNavigator(navController)
+}
+
+
+internal enum class MainTab(
+ val iconResId: Int,
+ internal val contentDescription: String,
+ val route: MainTabRoute,
+) {
+ HOME(
+ iconResId = R.drawable.ic_home,
+ contentDescription = "홈",
+ MainTabRoute.Home
+ ),
+ RECIPE_RECOMMEND(
+ iconResId = R.drawable.ic_recipe_recommend,
+ contentDescription = "레시피 추천",
+ MainTabRoute.RecipeRecommend,
+ );
+
+ companion object {
+ @Composable
+ fun find(predicate: @Composable (MainTabRoute) -> Boolean): MainTab? {
+ return entries.find { predicate(it.route) }
+ }
+
+ @Composable
+ fun contains(predicate: @Composable (Route) -> Boolean): Boolean {
+ return entries.map { it.route }.any { predicate(it) }
+ }
+ }
+}
diff --git a/Android/feature/main/src/main/java/com/sundaegukbap/banchango/feature/main/MainScreen.kt b/Android/feature/main/src/main/java/com/sundaegukbap/banchango/feature/main/MainScreen.kt
new file mode 100644
index 0000000..cb008ac
--- /dev/null
+++ b/Android/feature/main/src/main/java/com/sundaegukbap/banchango/feature/main/MainScreen.kt
@@ -0,0 +1,48 @@
+package com.sundaegukbap.banchango.feature.main
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Scaffold
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import androidx.navigation.compose.NavHost
+import com.sundaegukbap.banchango.feature.home.navigation.homeNavGraph
+import com.sundaegukbap.banchango.feature.reciperecommend.RecipesRecommendScreen
+import com.sundaegukbap.banchango.feature.reciperecommend.navigation.recipeRecommendNavGraph
+import kotlinx.collections.immutable.toPersistentList
+
+@Composable
+internal fun MainScreen(
+ navigator: MainNavigator = rememberMainNavigator(),
+ onChangeDarkTheme: (Boolean) -> Unit,
+) {
+ Scaffold(
+ content = { padding ->
+ Box(
+ modifier = Modifier
+ .fillMaxSize()
+ .background(MaterialTheme.colorScheme.surface)
+ ) {
+ NavHost(
+ navController = navigator.navController,
+ startDestination = navigator.startDestination
+ ) {
+ homeNavGraph(padding = padding)
+ recipeRecommendNavGraph(padding = padding)
+ }
+ }
+ },
+ bottomBar = {
+ MainBottomBar(
+ visible = navigator.shouldShowBottomBar(),
+ tabs = MainTab.entries.toPersistentList(),
+ currentTab = navigator.currentTab,
+ onTabSelected = { navigator.navigate(it) }
+ )
+ }
+ )
+}
diff --git a/Android/feature/main/src/main/res/drawable/ic_home.xml b/Android/feature/main/src/main/res/drawable/ic_home.xml
new file mode 100644
index 0000000..20cb4d6
--- /dev/null
+++ b/Android/feature/main/src/main/res/drawable/ic_home.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Android/feature/main/src/main/res/drawable/ic_recipe_recommend.xml b/Android/feature/main/src/main/res/drawable/ic_recipe_recommend.xml
new file mode 100644
index 0000000..13285cc
--- /dev/null
+++ b/Android/feature/main/src/main/res/drawable/ic_recipe_recommend.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/Android/feature/main/src/test/java/com/sundaegukbap/banchango/feature/main/.gitkeep b/Android/feature/main/src/test/java/com/sundaegukbap/banchango/feature/main/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/Android/feature/reciperecommend/.gitignore b/Android/feature/reciperecommend/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/Android/feature/reciperecommend/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Android/feature/reciperecommend/build.gradle.kts b/Android/feature/reciperecommend/build.gradle.kts
new file mode 100644
index 0000000..b417871
--- /dev/null
+++ b/Android/feature/reciperecommend/build.gradle.kts
@@ -0,0 +1,77 @@
+plugins {
+ alias(libs.plugins.android.library)
+ alias(libs.plugins.jetbrains.kotlin.android)
+ alias(libs.plugins.org.jetbrains.kotlin.kapt)
+ alias(libs.plugins.hilt)
+}
+
+android {
+ namespace = "com.sundaegukbap.banchango.feature.reciperecommend"
+ compileSdk = 34
+
+ defaultConfig {
+ minSdk = 28
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles("consumer-rules.pro")
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_17
+ targetCompatibility = JavaVersion.VERSION_17
+ }
+ kotlinOptions {
+ jvmTarget = "17"
+ }
+ buildFeatures {
+ compose = true
+ }
+ composeOptions {
+ kotlinCompilerExtensionVersion = "1.5.1"
+ }
+}
+
+dependencies {
+ implementation(project(":core:model"))
+ implementation(project(":core:designsystem"))
+ implementation(project(":core:navigation"))
+ implementation(libs.androidx.core.ktx)
+ implementation(libs.androidx.lifecycle.runtime.ktx)
+ implementation(libs.androidx.activity.compose)
+ implementation(platform(libs.androidx.compose.bom))
+ implementation(libs.androidx.ui)
+ implementation(libs.androidx.ui.graphics)
+ implementation(libs.androidx.ui.tooling.preview)
+ implementation(libs.androidx.material3)
+ implementation(libs.androidx.lifecycle.runtime.compose.android)
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.androidx.junit)
+ androidTestImplementation(libs.androidx.espresso.core)
+ androidTestImplementation(platform(libs.androidx.compose.bom))
+ androidTestImplementation(libs.androidx.ui.test.junit4)
+ debugImplementation(libs.androidx.ui.tooling)
+ debugImplementation(libs.androidx.ui.test.manifest)
+
+ implementation(libs.dagger.hilt.android)
+ kapt(libs.dagger.hilt.compiler)
+ implementation(libs.lifecycle.viewmodel.ktx)
+
+ // navigation
+ implementation(libs.navigation.compose)
+ implementation(libs.hilt.navigation.compose)
+
+ // status bar
+ implementation(libs.accompanist.systemuicontroller)
+
+ // glide
+ implementation(libs.glide.compose)
+}
diff --git a/Android/feature/reciperecommend/consumer-rules.pro b/Android/feature/reciperecommend/consumer-rules.pro
new file mode 100644
index 0000000..e69de29
diff --git a/Android/feature/reciperecommend/proguard-rules.pro b/Android/feature/reciperecommend/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/Android/feature/reciperecommend/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/Android/feature/reciperecommend/src/androidTest/java/com/sundaegukbap/banchango/feature/.gitkeep b/Android/feature/reciperecommend/src/androidTest/java/com/sundaegukbap/banchango/feature/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/Android/feature/reciperecommend/src/main/AndroidManifest.xml b/Android/feature/reciperecommend/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..8072ee0
--- /dev/null
+++ b/Android/feature/reciperecommend/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
+
diff --git a/Android/app/src/main/java/com/sundaegukbap/banchango/presentation/reciperecommend/RecipeCard.kt b/Android/feature/reciperecommend/src/main/java/com/sundaegukbap/banchango/feature/reciperecommend/RecipeCard.kt
similarity index 90%
rename from Android/app/src/main/java/com/sundaegukbap/banchango/presentation/reciperecommend/RecipeCard.kt
rename to Android/feature/reciperecommend/src/main/java/com/sundaegukbap/banchango/feature/reciperecommend/RecipeCard.kt
index 10f5e24..97159c8 100644
--- a/Android/app/src/main/java/com/sundaegukbap/banchango/presentation/reciperecommend/RecipeCard.kt
+++ b/Android/feature/reciperecommend/src/main/java/com/sundaegukbap/banchango/feature/reciperecommend/RecipeCard.kt
@@ -1,4 +1,4 @@
-package com.sundaegukbap.banchango.presentation.reciperecommend
+package com.sundaegukbap.banchango.feature.reciperecommend
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
@@ -19,14 +19,13 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
-import com.sundaegukbap.banchango.core.designsystem.NetworkImage
-import com.sundaegukbap.banchango.model.Recipe
-import com.sundaegukbap.banchango.ui.theme.BanchangoTheme
+import com.sundaegukbap.banchango.core.designsystem.component.NetworkImage
+import com.sundaegukbap.banchango.core.designsystem.theme.BanchangoTheme
@Composable
fun RecipeCard(
page: Int,
- recipe: Recipe,
+ recipe: com.sundaegukbap.banchango.Recipe,
onHateClick: (page: Int) -> Unit = {},
onLikeClick: (page: Int) -> Unit = {},
) {
@@ -47,7 +46,7 @@ fun RecipeCard(
@Composable
private fun RecipeInfo(
- recipe: Recipe,
+ recipe: com.sundaegukbap.banchango.Recipe,
page: Int,
onHateClick: (page: Int) -> Unit,
onLikeClick: (page: Int) -> Unit
@@ -99,7 +98,7 @@ private fun RecipeInfo(
fun RecipeCardPreview() {
BanchangoTheme {
RecipeCard(
- page = 1, recipe = Recipe(
+ page = 1, recipe = com.sundaegukbap.banchango.Recipe(
id = 1,
name = "간장계란볶음밥",
introduction = "아주 간단하면서 맛있는 계란간장볶음밥으로 한끼식사 만들어보세요. 아이들이 더 좋아할거예요.",
diff --git a/Android/app/src/main/java/com/sundaegukbap/banchango/presentation/reciperecommend/RecipeRecommendViewModel.kt b/Android/feature/reciperecommend/src/main/java/com/sundaegukbap/banchango/feature/reciperecommend/RecipeRecommendViewModel.kt
similarity index 91%
rename from Android/app/src/main/java/com/sundaegukbap/banchango/presentation/reciperecommend/RecipeRecommendViewModel.kt
rename to Android/feature/reciperecommend/src/main/java/com/sundaegukbap/banchango/feature/reciperecommend/RecipeRecommendViewModel.kt
index 1e33384..bb2ba4e 100644
--- a/Android/app/src/main/java/com/sundaegukbap/banchango/presentation/reciperecommend/RecipeRecommendViewModel.kt
+++ b/Android/feature/reciperecommend/src/main/java/com/sundaegukbap/banchango/feature/reciperecommend/RecipeRecommendViewModel.kt
@@ -1,7 +1,7 @@
-package com.sundaegukbap.banchango.presentation.reciperecommend
+package com.sundaegukbap.banchango.feature.reciperecommend
import androidx.lifecycle.ViewModel
-import com.sundaegukbap.banchango.model.Recipe
+import com.sundaegukbap.banchango.Recipe
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
diff --git a/Android/app/src/main/java/com/sundaegukbap/banchango/presentation/reciperecommend/RecipesRecommendScreen.kt b/Android/feature/reciperecommend/src/main/java/com/sundaegukbap/banchango/feature/reciperecommend/RecipesRecommendScreen.kt
similarity index 78%
rename from Android/app/src/main/java/com/sundaegukbap/banchango/presentation/reciperecommend/RecipesRecommendScreen.kt
rename to Android/feature/reciperecommend/src/main/java/com/sundaegukbap/banchango/feature/reciperecommend/RecipesRecommendScreen.kt
index 9de4207..2e7c008 100644
--- a/Android/app/src/main/java/com/sundaegukbap/banchango/presentation/reciperecommend/RecipesRecommendScreen.kt
+++ b/Android/feature/reciperecommend/src/main/java/com/sundaegukbap/banchango/feature/reciperecommend/RecipesRecommendScreen.kt
@@ -1,7 +1,7 @@
-package com.sundaegukbap.banchango.presentation.reciperecommend
+package com.sundaegukbap.banchango.feature.reciperecommend
-import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.pager.VerticalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.runtime.Composable
@@ -13,22 +13,19 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.launch
-@OptIn(ExperimentalFoundationApi::class)
@Composable
fun RecipesRecommendScreen(
- modifier: Modifier = Modifier,
+ padding: PaddingValues,
viewModel: RecipeRecommendViewModel = hiltViewModel(),
) {
val recipesUiState by viewModel.recipes.collectAsStateWithLifecycle()
-
- val pagerState = rememberPagerState(
- pageCount = {
- recipesUiState.size
- }
- )
+ val pagerState = rememberPagerState(pageCount = { recipesUiState.size })
val coroutineScope = rememberCoroutineScope()
+
+ viewModel.getRecipeRecommendation()
+
VerticalPager(
- modifier = modifier,
+ modifier = Modifier.padding(padding),
state = pagerState,
contentPadding = PaddingValues(vertical = 200.dp, horizontal = 40.dp),
pageSpacing = 40.dp,
diff --git a/Android/feature/reciperecommend/src/main/java/com/sundaegukbap/banchango/feature/reciperecommend/navigation/RecipeRecommendNavigation.kt b/Android/feature/reciperecommend/src/main/java/com/sundaegukbap/banchango/feature/reciperecommend/navigation/RecipeRecommendNavigation.kt
new file mode 100644
index 0000000..25f0f4e
--- /dev/null
+++ b/Android/feature/reciperecommend/src/main/java/com/sundaegukbap/banchango/feature/reciperecommend/navigation/RecipeRecommendNavigation.kt
@@ -0,0 +1,19 @@
+package com.sundaegukbap.banchango.feature.reciperecommend.navigation
+
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.navigation.NavController
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.NavOptions
+import androidx.navigation.compose.composable
+import com.sundaegukbap.banchango.feature.reciperecommend.RecipesRecommendScreen
+import com.sundaegukbap.banchango.navigation.MainTabRoute
+
+fun NavController.navigateRecipeRecommend(navOptions: NavOptions) {
+ navigate(MainTabRoute.RecipeRecommend, navOptions)
+}
+
+fun NavGraphBuilder.recipeRecommendNavGraph(padding: PaddingValues) {
+ composable {
+ RecipesRecommendScreen(padding)
+ }
+}
diff --git a/Android/feature/reciperecommend/src/test/java/com/sundaegukbap/banchango/feature/.gitkeep b/Android/feature/reciperecommend/src/test/java/com/sundaegukbap/banchango/feature/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/Android/gradle/libs.versions.toml b/Android/gradle/libs.versions.toml
index 9366f2d..3f958be 100644
--- a/Android/gradle/libs.versions.toml
+++ b/Android/gradle/libs.versions.toml
@@ -11,11 +11,17 @@ composeBom = "2024.05.00"
hilt = "2.44"
lifecycleViewModelKtx = "2.8.0"
ktlint = "11.1.0"
-composeNavigation = "2.7.7"
+composeNavigation = "2.8.0-beta02"
composeHiltNavigation = "1.2.0"
acompanistSystemUiController = "0.27.0"
lifecycleRuntimeComposeAndroid = "2.8.0"
glide = "1.0.0-beta01"
+jetbrainsKotlinJvm = "1.9.0"
+appcompat = "1.6.1"
+material = "1.12.0"
+material3Android = "1.2.1"
+serialization = "1.6.3"
+kotlinxImmutable = "0.3.7"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -35,11 +41,16 @@ androidx-material3 = { group = "androidx.compose.material3", name = "material3"
dagger-hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
dagger-hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" }
lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleViewModelKtx" }
-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "composeNavigation" }
hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "composeHiltNavigation" }
accompanist-systemuicontroller = { group = "com.google.accompanist", name = "accompanist-systemuicontroller", version.ref = "acompanistSystemUiController" }
androidx-lifecycle-runtime-compose-android = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose-android", version.ref = "lifecycleRuntimeComposeAndroid" }
glide-compose = { group = "com.github.bumptech.glide", name = "compose", version.ref = "glide" }
+androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
+material = { group = "com.google.android.material", name = "material", version.ref = "material" }
+androidx-material3-android = { group = "androidx.compose.material3", name = "material3-android", version.ref = "material3Android" }
+navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "composeNavigation" }
+kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization" }
+kotlinx-immutable = { group = "org.jetbrains.kotlinx", name = "kotlinx-collections-immutable", version.ref = "kotlinxImmutable" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
@@ -47,4 +58,7 @@ jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref =
org-jetbrains-kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" }
hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" }
ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" }
+jetbrains-kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "jetbrainsKotlinJvm" }
+android-library = { id = "com.android.library", version.ref = "agp" }
+kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
diff --git a/Android/settings.gradle.kts b/Android/settings.gradle.kts
index 5391526..811b5c8 100644
--- a/Android/settings.gradle.kts
+++ b/Android/settings.gradle.kts
@@ -21,3 +21,11 @@ dependencyResolutionManagement {
rootProject.name = "banchango"
include(":app")
+include(":core:domain")
+include(":core:model")
+include(":core:designsystem")
+include(":feature:reciperecommend")
+include(":feature:main")
+include(":core:data-api")
+include(":core:navigation")
+include(":feature:home")