diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml
index f26700233..56dafa4a3 100644
--- a/.github/workflows/android.yml
+++ b/.github/workflows/android.yml
@@ -46,12 +46,11 @@ jobs:
- name: Grant execute permission for gradlew
run: chmod +x gradlew
+ - name: Clear Gradle Cache
+ run: ./gradlew clean
+
- name: Build for debug with Gradle
run: ./gradlew assembleDebug
- - name: Upload APK
- if: github.ref == 'refs/heads/master'
- uses: actions/upload-artifact@v4
- with:
- name: app
- path: app/build/outputs/apk/release
\ No newline at end of file
+# - name: unit test
+# run: ./gradlew test
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 8049eeb09..334469fb2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,6 @@
local.properties
deploymentTargetDropDown.xml
/config.json
+/.idea/other.xml
+/.idea/deploymentTargetSelector.xml
+.kotlin/
diff --git a/.idea/androidTestResultsUserPreferences.xml b/.idea/androidTestResultsUserPreferences.xml
index 8bc7bee8d..4cd478d43 100644
--- a/.idea/androidTestResultsUserPreferences.xml
+++ b/.idea/androidTestResultsUserPreferences.xml
@@ -3,6 +3,19 @@
diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
index 70faf41cc..d88922f26 100644
--- a/.idea/deploymentTargetSelector.xml
+++ b/.idea/deploymentTargetSelector.xml
@@ -4,10 +4,10 @@
-
+
-
+
diff --git a/.idea/git_toolbox_blame.xml b/.idea/git_toolbox_blame.xml
new file mode 100644
index 000000000..7dc124965
--- /dev/null
+++ b/.idea/git_toolbox_blame.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 6397ddf49..7df13adca 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -25,7 +25,6 @@
-
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
index fdf8d994a..ae3f30ae1 100644
--- a/.idea/kotlinc.xml
+++ b/.idea/kotlinc.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/other.xml b/.idea/other.xml
index a76f1180a..49481ad49 100644
--- a/.idea/other.xml
+++ b/.idea/other.xml
@@ -256,6 +256,17 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -312,17 +323,6 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/README.md b/README.md
index c8ede7100..edb44bb68 100644
--- a/README.md
+++ b/README.md
@@ -43,8 +43,8 @@
## 멀티 모듈의 관심사 분리 및 아키텍처 적용
-## MVVM 적용
-
+## UI Layer 패턴 - MVVM+MVI 혼합
+
### 데이터 전달 및 상태관리 구체화 구조
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 4dbf589dc..6568ae17f 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,12 +1,11 @@
import java.util.*
plugins {
- id("com.android.application")
+ alias(libs.plugins.android.application)
id("com.google.android.gms.oss-licenses-plugin")
- id("org.jetbrains.kotlin.android")
- id("dagger.hilt.android.plugin")
- id("com.google.dagger.hilt.android")
- id("com.google.gms.google-services")
+ alias(libs.plugins.kotlin.android)
+ alias(libs.plugins.hilt.android)
+ alias(libs.plugins.google.services)
kotlin("kapt")
}
@@ -22,12 +21,13 @@ android {
applicationId = "com.hmoa.app"
minSdk = 26
targetSdk = 34
- versionCode = 23
- versionName = "1.1.2"
+ versionCode = 36
+ versionName = "1.3.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
manifestPlaceholders["REDIRECTION_PATH"] = localProperties["REDIRECTION_PATH"] as String
buildConfigField("String", "NATIVE_APP_KEY", localProperties["NATIVE_APP_KEY"] as String)
+ buildConfigField("String", "BOOTPAY_APPLICATION_ID", localProperties["BOOTPAY_APPLICATION_ID"] as String)
}
signingConfigs {
@@ -50,10 +50,6 @@ android {
signingConfig = signingConfigs.getByName("release")
isDebuggable = false
}
- debug {
- signingConfig = signingConfigs.getByName("debug")
- isDebuggable = true
- }
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
@@ -66,33 +62,18 @@ android {
compose = true
}
composeOptions {
- kotlinCompilerExtensionVersion = "1.5.0"
+ kotlinCompilerExtensionVersion = "1.5.7"
}
packaging {
resources {
excludes += "META-INF/gradle/incremental.annotation.processors"
}
}
-
- applicationVariants.all {
- this.mergeResourcesProvider.configure {
- doLast {
- copy {
- from(":HMOA_ANDROID_SECRET")
- }
- }
- }
- }
-
}
dependencies {
- val hilt_version = "2.48.1"
- val hilt_viewmodel_version = "1.0.0-alpha03"
- val hilt_nav_compose_version = "1.0.0"
-
implementation(project(":feature-home"))
implementation(project(":feature-authentication"))
implementation(project(":feature-userInfo"))
@@ -100,48 +81,31 @@ dependencies {
implementation(project(":feature-perfume"))
implementation(project(":feature-brand"))
implementation(project(":feature-hpedia"))
- implementation(project(":feature-like"))
implementation(project(":feature-fcm"))
implementation(project(":feature-magazine"))
+ implementation(project(":feature-hbti"))
implementation(project(":core-designsystem"))
implementation(project(":core-model"))
implementation(project(":core-domain"))
implementation(project(":core-repository"))
implementation(project(":core-common"))
- implementation("com.kakao.sdk:v2-all:2.19.0")// 전체 모듈 설치, 2.11.0 버전부터 지원
- implementation("com.kakao.sdk:v2-user:2.19.0") // 카카오 로그인 API 모듈
- implementation("com.kakao.sdk:v2-talk:2.19.0") // 카카오톡 채널, 카카오톡 소셜, 카카오톡 메시지 API 모듈
- implementation("com.kakao.sdk:v2-share:2.19.0") // 카카오톡 공유 API 모듈
- implementation("com.kakao.sdk:v2-friend:2.19.0") // 피커 API 모듈
- implementation("com.kakao.sdk:v2-cert:2.19.0") // 카카오 인증서비스 API 모듈
- implementation("com.google.dagger:hilt-android:$hilt_version")
- implementation("com.google.dagger:hilt-compiler:$hilt_version")
- kapt("com.google.dagger:hilt-android-compiler:$hilt_version")
- testAnnotationProcessor("com.google.dagger:hilt-compiler:$hilt_version")
- implementation("androidx.hilt:hilt-navigation-compose:$hilt_nav_compose_version")
- kapt("androidx.hilt:hilt-compiler:$hilt_viewmodel_version")
- implementation("androidx.compose.material:material:1.2.0-beta02")
- implementation("androidx.compose.material3:material3:1.2.0")
- implementation("androidx.compose.ui:ui-tooling-preview")
- implementation("androidx.compose.ui:ui:1.1.0")
- implementation("androidx.navigation:navigation-compose:2.7.0")
- implementation("androidx.core:core-ktx:1.9.0")
- implementation("androidx.appcompat:appcompat:1.6.1")
- implementation("com.google.android.material:material:1.8.0")
- implementation("androidx.core:core-splashscreen:1.2.0-alpha01")
- // Import the Firebase BoM
- implementation(platform("com.google.firebase:firebase-bom:32.8.1"))
- // When using the BoM, don't specify versions in Firebase dependencies
- implementation("com.google.firebase:firebase-messaging:21.1.0")
- implementation("com.google.firebase:firebase-analytics")
- //google login
- implementation("com.google.android.gms:play-services-auth:21.0.0")
- implementation("com.google.gms:google-services:4.4.1")
- //open licence
- implementation("com.google.android.gms:play-services-oss-licenses:17.0.0")
-
- testImplementation("junit:junit:4.13.2")
- androidTestImplementation("androidx.test.ext:junit:1.1.5")
- androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
-}
\ No newline at end of file
+ implementation(libs.app.update.ktx)
+ implementation(libs.bootpay) //부트페이
+ implementation(libs.bundles.kakao.login) // kakao
+ implementation(libs.bundles.hilt) // hilt
+ kapt(libs.hilt.android.compiler)
+ testAnnotationProcessor(libs.hilt.compiler)
+ kapt(libs.hilt.viewmodel)
+ implementation(libs.bundles.ui)
+ implementation(libs.navigation.compose)
+ implementation(libs.bundles.basic)
+ implementation(libs.google.material)
+ implementation(libs.splash.screen) // splash
+ implementation(libs.bundles.firebase) // firebase
+ implementation(libs.bundles.google.login) //google
+ implementation(libs.open.licenses)
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.junit.ext)
+ androidTestImplementation(libs.espresso)
+}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c11608c28..2848e56b9 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,6 +7,7 @@
+
@@ -63,7 +64,7 @@
@@ -71,4 +72,4 @@
-
\ No newline at end of file
+
diff --git a/app/src/main/java/com/hmoa/app/navigation/NavHost.kt b/app/src/main/java/com/hmoa/app/navigation/NavHost.kt
index 319acd6c5..3827b9974 100644
--- a/app/src/main/java/com/hmoa/app/navigation/NavHost.kt
+++ b/app/src/main/java/com/hmoa/app/navigation/NavHost.kt
@@ -3,26 +3,92 @@ package com.hmoa.app.navigation
import androidx.compose.runtime.Composable
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
-import androidx.navigation.compose.composable
-import com.example.feature_userinfo.*
-import com.hmoa.feature_authentication.navigation.*
+import com.hmoa.feature_authentication.navigation.loginScreen
+import com.hmoa.feature_authentication.navigation.navigateToLogin
+import com.hmoa.feature_authentication.navigation.navigateToPickNickname
+import com.hmoa.feature_authentication.navigation.navigateToPickPersonalInfo
+import com.hmoa.feature_authentication.navigation.navigateToSignup
+import com.hmoa.feature_authentication.navigation.pickNicknameScreen
+import com.hmoa.feature_authentication.navigation.pickPersonalInfoScreen
+import com.hmoa.feature_authentication.navigation.signupScreen
import com.hmoa.feature_brand.navigation.brandScreen
import com.hmoa.feature_brand.navigation.brandSearchScreen
import com.hmoa.feature_brand.navigation.navigateToBrand
-import com.hmoa.feature_community.Navigation.*
+import com.hmoa.feature_community.Navigation.navigateToCommunityCommentEditRoute
+import com.hmoa.feature_community.Navigation.navigateToCommunityDescriptionRoute
+import com.hmoa.feature_community.Navigation.navigateToCommunityEditRoute
+import com.hmoa.feature_community.Navigation.navigateToCommunityPage
+import com.hmoa.feature_community.Navigation.navigateToCommunityPostRoute
+import com.hmoa.feature_community.Navigation.navigateToCommunityRoute
+import com.hmoa.feature_community.Navigation.navigateToCommunitySearchRoute
+import com.hmoa.feature_community.Navigation.nestedCommunityGraph
import com.hmoa.feature_fcm.alarmRoute
-import com.hmoa.feature_home.navigation.*
+import com.hmoa.feature_hbti.navigation.addAddress
+import com.hmoa.feature_hbti.navigation.editReview
+import com.hmoa.feature_hbti.navigation.hbtiProcessScreen
+import com.hmoa.feature_hbti.navigation.hbtiScreen
+import com.hmoa.feature_hbti.navigation.hbtiSurveyLoadingScreen
+import com.hmoa.feature_hbti.navigation.hbtiSurveyResultScreen
+import com.hmoa.feature_hbti.navigation.hbtiSurveyScreen
+import com.hmoa.feature_hbti.navigation.navigateToAddAddress
+import com.hmoa.feature_hbti.navigation.navigateToEditReview
+import com.hmoa.feature_hbti.navigation.navigateToHbti
+import com.hmoa.feature_hbti.navigation.navigateToHbtiProcess
+import com.hmoa.feature_hbti.navigation.navigateToHbtiSurvey
+import com.hmoa.feature_hbti.navigation.navigateToHbtiSurveyLoading
+import com.hmoa.feature_hbti.navigation.navigateToHbtiSurveyResult
+import com.hmoa.feature_hbti.navigation.navigateToNotePick
+import com.hmoa.feature_hbti.navigation.navigateToNotePickResult
+import com.hmoa.feature_hbti.navigation.navigateToOrder
+import com.hmoa.feature_hbti.navigation.navigateToOrderResult
+import com.hmoa.feature_hbti.navigation.navigateToPerfumeRecommendation
+import com.hmoa.feature_hbti.navigation.navigateToPerfumeRecommendationResult
+import com.hmoa.feature_hbti.navigation.navigateToReview
+import com.hmoa.feature_hbti.navigation.navigateToWriteReview
+import com.hmoa.feature_hbti.navigation.notePickResult
+import com.hmoa.feature_hbti.navigation.notePickScreen
+import com.hmoa.feature_hbti.navigation.order
+import com.hmoa.feature_hbti.navigation.orderResult
+import com.hmoa.feature_hbti.navigation.perfumeRecommendationResultRoute
+import com.hmoa.feature_hbti.navigation.perfumeRecommendationRoute
+import com.hmoa.feature_hbti.navigation.review
+import com.hmoa.feature_hbti.navigation.writeReview
+import com.hmoa.feature_home.navigation.allPerfumeScreen
+import com.hmoa.feature_home.navigation.homeScreen
+import com.hmoa.feature_home.navigation.navigateToAllPerfume
+import com.hmoa.feature_home.navigation.navigateToHome
+import com.hmoa.feature_home.navigation.perfumeSearchScreen
import com.hmoa.feature_hpedia.Navigation.navigateToHPedia
import com.hmoa.feature_hpedia.Navigation.navigateToHPediaDescRoute
import com.hmoa.feature_hpedia.Navigation.navigateToHPediaSearchRoute
import com.hmoa.feature_hpedia.Navigation.nestedHPediaGraph
-import com.hmoa.feature_like.Screen.LIKE_ROUTE
-import com.hmoa.feature_like.Screen.LikeRoute
-import com.hmoa.feature_like.Screen.navigateToLike
import com.hmoa.feature_magazine.Navigation.magazineDesc
import com.hmoa.feature_magazine.Navigation.magazineMain
import com.hmoa.feature_magazine.Navigation.navigateToMagazineDesc
-import com.hmoa.feature_perfume.navigation.*
+import com.hmoa.feature_perfume.navigation.createNewPerfumeComment
+import com.hmoa.feature_perfume.navigation.editMyPerfumeComment
+import com.hmoa.feature_perfume.navigation.navigateToCreateNewperfumeComment
+import com.hmoa.feature_perfume.navigation.navigateToPerfume
+import com.hmoa.feature_perfume.navigation.navigateToPerfumeComment
+import com.hmoa.feature_perfume.navigation.navigateToSpecificPerfumeComment
+import com.hmoa.feature_perfume.navigation.perfumeComment
+import com.hmoa.feature_perfume.navigation.perfumeScreen
+import com.hmoa.feature_perfume.navigation.specificComment
+import com.hmoa.feature_userinfo.navigation.navigateToBack
+import com.hmoa.feature_userinfo.navigation.navigateToEditProfilePage
+import com.hmoa.feature_userinfo.navigation.navigateToMyActivity
+import com.hmoa.feature_userinfo.navigation.navigateToMyBirth
+import com.hmoa.feature_userinfo.navigation.navigateToMyCommentPage
+import com.hmoa.feature_userinfo.navigation.navigateToMyFavoriteCommentPage
+import com.hmoa.feature_userinfo.navigation.navigateToMyFavoritePerfume
+import com.hmoa.feature_userinfo.navigation.navigateToMyGenderPage
+import com.hmoa.feature_userinfo.navigation.navigateToMyInfoPage
+import com.hmoa.feature_userinfo.navigation.navigateToMyPostPage
+import com.hmoa.feature_userinfo.navigation.navigateToMyReview
+import com.hmoa.feature_userinfo.navigation.navigateToOrderRecord
+import com.hmoa.feature_userinfo.navigation.navigateToRefund
+import com.hmoa.feature_userinfo.navigation.navigateToRefundRecord
+import com.hmoa.feature_userinfo.navigation.nestedUserInfoGraph
@Composable
fun SetUpNavGraph(
@@ -41,7 +107,7 @@ fun SetUpNavGraph(
navController.navigateToPerfume(perfumeId)
},
onAllPerfumeClick = { navController.navigateToAllPerfume(it) },
- onHbtiClick = { })
+ onHbtiClick = { navController.navigateToHbti() })
perfumeSearchScreen(onBackClick = navController::navigateToBack)
allPerfumeScreen(
onNavLogin = navController::navigateToLogin,
@@ -67,30 +133,29 @@ fun SetUpNavGraph(
onPickNicknameClick = navController::navigateToPickNickname
)
- /** like 모듈 */
- composable(LIKE_ROUTE) {
- LikeRoute(
- onNavPerfumeDesc = navController::navigateToPerfume,
- onNavHome = navController::navigateToHome,
- onErrorHandleLoginAgain = navController::navigateToLogin
- )
- }
-
/** user info 모듈 */
this.nestedUserInfoGraph(
- onNavLogin = navController::navigateToLogin,
- onNavBack = navController::navigateToBack,
- onNavCommunity = navController::navigateToCommunityDescriptionRoute,
- onNavEditProfile = navController::navigateToEditProfilePage,
- onNavManageMyInfo = navController::navigateToMyInfoPage,
- onNavMyActivity = navController::navigateToMyActivity,
- onNavMyFavoriteComment = navController::navigateToMyFavoriteCommentPage,
- onNavMyPost = navController::navigateToMyPostPage,
- onNavMyComment = navController::navigateToMyCommentPage,
- onNavMyBirth = navController::navigateToMyBirth,
- onNavMyGender = navController::navigateToMyGenderPage,
- onNavMyPerfume = navController::navigateToLike,
- onNavPerfume = navController::navigateToPerfume,
+ navHome = navController::navigateToHome,
+ navLogin = navController::navigateToLogin,
+ navReview = navController::navigateToReview,
+ navBack = navController::navigateToBack,
+ navCommunity = navController::navigateToCommunityDescriptionRoute,
+ navEditPost = navController::navigateToCommunityEditRoute,
+ navEditProfile = navController::navigateToEditProfilePage,
+ navManageMyInfo = navController::navigateToMyInfoPage,
+ navMyActivity = navController::navigateToMyActivity,
+ navMyFavoriteComment = navController::navigateToMyFavoriteCommentPage,
+ navMyPost = navController::navigateToMyPostPage,
+ navMyComment = navController::navigateToMyCommentPage,
+ navMyReview = navController::navigateToMyReview,
+ navMyBirth = navController::navigateToMyBirth,
+ navMyGender = navController::navigateToMyGenderPage,
+ navMyPerfume = navController::navigateToMyFavoritePerfume,
+ navPerfume = navController::navigateToPerfume,
+ navOrderRecord = navController::navigateToOrderRecord,
+ navReviewWrite = navController::navigateToWriteReview,
+ navRefund = navController::navigateToRefund,
+ navRefundRecord = navController::navigateToRefundRecord,
appVersion = appVersion
)
@@ -114,9 +179,7 @@ fun SetUpNavGraph(
navCommunityCommentEdit = navController::navigateToCommunityCommentEditRoute,
onErrorHandleLoginAgain = navController::navigateToLogin,
navLogin = navController::navigateToLogin,
- navHome = navController::navigateToHome,
- navHPedia = navController::navigateToHPedia,
- popStack = { navController.popBackStack() }
+ navHPedia = navController::navigateToHPedia
)
/** perfume 모듈 */
@@ -168,9 +231,78 @@ fun SetUpNavGraph(
onNavMagazineDesc = navController::navigateToMagazineDesc
)
magazineDesc(
- onNavBack = navController::navigateToBack,
- onNavLogin = navController::navigateToLogin,
- onNavDesc = navController::navigateToMagazineDesc
+ navBack = navController::navigateToBack,
+ navLogin = navController::navigateToLogin,
+ navDesc = navController::navigateToMagazineDesc
+ )
+
+ /** hbti 모듈 */
+ hbtiScreen(
+ navBack = navController::navigateToBack,
+ navHome = navController::navigateToHome,
+ navReview = navController::navigateToReview,
+ onHbtiSurveyClick = navController::navigateToHbtiSurvey,
+ onAfterOrderClick = navController::navigateToPerfumeRecommendation,
+ navLogin = navController::navigateToLogin,
+ )
+ hbtiSurveyScreen(
+ onBackClick = navController::navigateToBack,
+ onErrorHandleLoginAgain = navController::navigateToLogin,
+ onNextClick = navController::navigateToHbtiSurveyLoading
+ )
+ hbtiSurveyResultScreen(
+ onErrorHandleLoginAgain = navController::navigateToLogin,
+ onBackClick = navController::navigateToBack,
+ onHbtiProcessClick = navController::navigateToHbtiProcess
+ )
+ hbtiSurveyLoadingScreen(
+ onNextScreen = navController::navigateToHbtiSurveyResult,
+ onBackClick = navController::navigateToBack,
+ )
+ hbtiProcessScreen(
+ navLogin = navController::navigateToLogin,
+ onBackClick = navController::navigateToBack,
+ onNextClick = navController::navigateToNotePick
+ )
+ notePickScreen(
+ onBackClick = navController::navigateToBack,
+ onNextClick = navController::navigateToNotePickResult,
+ onErrorHandleLoginAgain = navController::navigateToLogin,
+ onBackToHbtiScreen = navController::navigateToHbti
+ )
+ notePickResult(
+ onBackClick = navController::navigateToBack,
+ onNextClick = navController::navigateToOrder,
+ onBackToHbtiScreen = navController::navigateToHbti
+ )
+ order(
+ navBack = navController::navigateToBack,
+ navAddAddress = navController::navigateToAddAddress,
+ navOrderResult = navController::navigateToOrderResult,
+ navLogin = navController::navigateToLogin
+ )
+ addAddress(
+ navOrder = navController::navigateToOrder,
+ navLogin = navController::navigateToLogin
+ )
+ orderResult(navHbti = navController::navigateToHbti)
+ perfumeRecommendationRoute(
+ onBackClick = navController::navigateToBack,
+ onNextClick = navController::navigateToPerfumeRecommendationResult
+ )
+ perfumeRecommendationResultRoute(
+ onBackClick = navController::navigateToBack,
+ navPerfumeDescription = { id -> navController.navigateToPerfume(id) },
+ navHome = navController::navigateToHome,
+ navLogin = navController::navigateToLogin
+ )
+ writeReview(navBack = navController::navigateToBack, navReview = navController::navigateToReview)
+ review(
+ navBack = navController::navigateToBack,
+ navWriteReview = navController::navigateToWriteReview,
+ navEditReview = navController::navigateToEditReview,
+ navLogin = navController::navigateToLogin
)
+ editReview(navReview = navController::navigateToReview, navLogin = navController::navigateToLogin)
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/hmoa/app/FcmAppService.kt b/app/src/main/java/com/hmoa/app/service/FcmAppService.kt
similarity index 69%
rename from app/src/main/java/com/hmoa/app/FcmAppService.kt
rename to app/src/main/java/com/hmoa/app/service/FcmAppService.kt
index 10828577e..236698f7f 100644
--- a/app/src/main/java/com/hmoa/app/FcmAppService.kt
+++ b/app/src/main/java/com/hmoa/app/service/FcmAppService.kt
@@ -1,4 +1,4 @@
-package com.hmoa.app
+package com.hmoa.app.service
import android.app.Notification
import android.app.NotificationChannel
@@ -8,28 +8,36 @@ import android.content.Context
import android.content.Intent
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
+import com.hmoa.app.view.MainActivity
class FcmAppService : FirebaseMessagingService() {
override fun onNewToken(token: String) {
super.onNewToken(token)
}
+
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
- if(remoteMessage.data.isNotEmpty()){
+ if (remoteMessage.data.isNotEmpty()) {
sendNotification(remoteMessage.data)
}
}
- private fun sendNotification(fcmData : Map){
+
+ private fun sendNotification(fcmData: Map) {
val CHANNEL_DEFAULT_IMPORTANCE = "channelId"
val ONGOING_NOTIFICATION = 1
- val notificationIntent = Intent(this, MainActivity::class.java).apply{
+ val notificationIntent = Intent(this, MainActivity::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
- putExtra("deeplink",fcmData["deeplink"])
- putExtra("id",fcmData["id"])
+ putExtra("deeplink", fcmData["deeplink"])
+ putExtra("id", fcmData["id"])
}
- val pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
+ val pendingIntent = PendingIntent.getActivity(
+ this,
+ 0,
+ notificationIntent,
+ PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
+ )
val notification = Notification.Builder(this, CHANNEL_DEFAULT_IMPORTANCE)
.setContentTitle(fcmData["title"])
@@ -41,9 +49,10 @@ class FcmAppService : FirebaseMessagingService() {
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
- val channel = NotificationChannel(CHANNEL_DEFAULT_IMPORTANCE, "HMOA Channel", NotificationManager.IMPORTANCE_DEFAULT)
+ val channel =
+ NotificationChannel(CHANNEL_DEFAULT_IMPORTANCE, "HMOA Channel", NotificationManager.IMPORTANCE_DEFAULT)
notificationManager.createNotificationChannel(channel)
notificationManager.notify(ONGOING_NOTIFICATION, notification)
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/hmoa/app/MainActivity.kt b/app/src/main/java/com/hmoa/app/view/MainActivity.kt
similarity index 61%
rename from app/src/main/java/com/hmoa/app/MainActivity.kt
rename to app/src/main/java/com/hmoa/app/view/MainActivity.kt
index 277e4b322..3b4ec8e22 100644
--- a/app/src/main/java/com/hmoa/app/MainActivity.kt
+++ b/app/src/main/java/com/hmoa/app/view/MainActivity.kt
@@ -1,4 +1,4 @@
-package com.hmoa.app
+package com.hmoa.app.view
import android.Manifest
import android.content.Intent
@@ -6,10 +6,10 @@ import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
-import android.os.Handler
-import android.os.Looper
import android.util.Log
import androidx.activity.compose.setContent
+import androidx.activity.result.ActivityResult
+import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.Box
@@ -19,7 +19,9 @@ import androidx.compose.material.DrawerValue
import androidx.compose.material.Scaffold
import androidx.compose.material.rememberDrawerState
import androidx.compose.material.rememberScaffoldState
-import androidx.compose.runtime.*
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
@@ -32,36 +34,40 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
-import com.example.feature_userinfo.UserInfoGraph
-import com.example.feature_userinfo.navigateToUserInfoGraph
+import com.google.android.material.snackbar.Snackbar
+import com.google.android.play.core.appupdate.AppUpdateInfo
+import com.google.android.play.core.appupdate.AppUpdateManager
+import com.google.android.play.core.appupdate.AppUpdateManagerFactory
+import com.google.android.play.core.appupdate.AppUpdateOptions
+import com.google.android.play.core.install.model.AppUpdateType
+import com.google.android.play.core.install.model.InstallStatus
+import com.google.android.play.core.install.model.UpdateAvailability
import com.google.firebase.messaging.FirebaseMessaging
+import com.hmoa.app.BuildConfig
import com.hmoa.app.navigation.SetUpNavGraph
-import com.hmoa.core_common.PERMISSION_REQUEST_CODE
+import com.hmoa.app.viewmodel.AppViewModel
import com.hmoa.core_common.permissions
import com.hmoa.core_designsystem.BottomScreen
import com.hmoa.core_designsystem.component.HomeTopBar
import com.hmoa.core_designsystem.component.MainBottomBar
-import com.hmoa.feature_authentication.navigation.AuthenticationRoute
+import com.hmoa.core_domain.entity.navigation.*
import com.hmoa.feature_brand.navigation.navigateToBrandSearch
-import com.hmoa.feature_community.Navigation.CommunityRoute
import com.hmoa.feature_fcm.navigateToAlarmScreen
-import com.hmoa.feature_home.navigation.HomeRoute
import com.hmoa.feature_home.navigation.navigateToHome
import com.hmoa.feature_home.navigation.navigateToPerfumeSearch
-import com.hmoa.feature_hpedia.Navigation.HPediaRoute
import com.hmoa.feature_hpedia.Navigation.navigateToHPedia
-import com.hmoa.feature_like.Screen.LIKE_ROUTE
-import com.hmoa.feature_magazine.Navigation.MagazineRoute
import com.hmoa.feature_magazine.Navigation.navigateToMagazineHome
-import com.hmoa.feature_perfume.navigation.PerfumeRoute
+import com.hmoa.feature_userinfo.navigation.navigateToUserInfoGraph
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
+import kr.co.bootpay.android.BootpayAnalytics
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private val viewModel: AppViewModel by viewModels()
private var initialRoute = AuthenticationRoute.Login.name
+ private val PERMISSION_REQUEST_CODE = 1001
private val needBottomBarScreens = listOf(
HomeRoute.Home.name,
CommunityRoute.CommunityHomeRoute.name,
@@ -69,29 +75,113 @@ class MainActivity : AppCompatActivity() {
HPediaRoute.HPedia.name,
"${HPediaRoute.HPediaSearchRoute.name}/{type}",
"${HPediaRoute.HPediaDescRoute.name}/{id}/{type}",
- UserInfoGraph.MyPage.name,
- UserInfoGraph.MyInfoRoute.name,
- UserInfoGraph.MyFavoriteCommentRoute.name,
- UserInfoGraph.MyActivityRoute.name,
- UserInfoGraph.MyCommentRoute.name,
- UserInfoGraph.MyPostRoute.name,
- LIKE_ROUTE,
+ UserInfoRoute.MyPage.name,
+ UserInfoRoute.MyInfoRoute.name,
+ UserInfoRoute.MyFavoriteCommentRoute.name,
+ UserInfoRoute.MyActivityRoute.name,
+ UserInfoRoute.MyCommentRoute.name,
+ UserInfoRoute.MyPostRoute.name,
+ UserInfoRoute.MyFavoritePerfumeRoute.name,
MagazineRoute.Magazine.name
)
+
+ private val needTopBarScreens = HomeRoute.Home.name
private val bottomNav = listOf(
BottomScreen.Home.name,
BottomScreen.HPedia.name,
BottomScreen.Magazine.name,
BottomScreen.MyPage.name
)
+ private lateinit var appUpdateManager: AppUpdateManager
+ private val activityResultLauncher =
+ registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) { result: ActivityResult ->
+ handleUpdateResult(result)
+ }
- private val needTopBarScreens = HomeRoute.Home.name
+ // Displays the snackbar notification and call to action.
+ fun popupSnackbarForCompleteUpdate() {
+ Snackbar.make(
+ findViewById(com.hmoa.core_designsystem.R.drawable.ic_fab),
+ "새로운 업데이트 다운로드가 완료되었습니다.",
+ Snackbar.LENGTH_INDEFINITE
+ ).apply {
+ setAction("재시작") { appUpdateManager.completeUpdate() }
+ show()
+ }
+ }
+
+ private fun checkImmediateUpdateAvailability() {
+ appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo ->
+ if (shouldTriggerImmediateUpdate(appUpdateInfo)) {
+ Log.d("checkUpdateAvailability", "ImemediateUpdate")
+ startImmediateUpdate(appUpdateInfo)
+ }
+ }.addOnFailureListener { e ->
+ Log.e("UpdateFlow", "Failed to check update availability", e)
+ }
+ }
+
+ private fun checkFlexibleUpdateAvailability() {
+ appUpdateManager.appUpdateInfo.addOnSuccessListener { appUpdateInfo ->
+ if (shouldTriggerFlexibleUpdate(appUpdateInfo)) {
+ Log.d("checkUpdateAvailability", "ImemediateUpdate")
+ startFlexibleUpdate(appUpdateInfo)
+ if (appUpdateInfo.installStatus() == InstallStatus.DOWNLOADED) {
+ popupSnackbarForCompleteUpdate()
+ }
+ }
+ }.addOnFailureListener { e ->
+ Log.e("UpdateFlow", "Failed to check update availability", e)
+ }
+ }
+
+
+ private fun shouldTriggerImmediateUpdate(appUpdateInfo: AppUpdateInfo): Boolean {
+ return appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE &&
+ appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.IMMEDIATE)
+ }
+
+ private fun shouldTriggerFlexibleUpdate(appUpdateInfo: AppUpdateInfo): Boolean {
+ return appUpdateInfo.updateAvailability() == UpdateAvailability.UPDATE_AVAILABLE &&
+ appUpdateInfo.isUpdateTypeAllowed(AppUpdateType.FLEXIBLE)
+ }
+
+
+ private fun startImmediateUpdate(appUpdateInfo: AppUpdateInfo) {
+ appUpdateManager.startUpdateFlowForResult(
+ appUpdateInfo,
+ activityResultLauncher,
+ AppUpdateOptions.newBuilder(AppUpdateType.IMMEDIATE).build()
+ )
+ }
+
+ private fun startFlexibleUpdate(appUpdateInfo: AppUpdateInfo) {
+ appUpdateManager.startUpdateFlowForResult(
+ appUpdateInfo,
+ activityResultLauncher,
+ AppUpdateOptions.newBuilder(AppUpdateType.FLEXIBLE).build()
+ )
+ }
+
+ private fun handleUpdateResult(result: ActivityResult) {
+ if (result.resultCode == RESULT_OK) {
+ Log.d("UpdateFlow", "Update flow completed successfully!")
+ } else {
+ Log.e("UpdateFlow", "Update flow failed! Result code: ${result.resultCode}")
+ // 필요시 재시도 로직 추가 가능
+ }
+ }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
installSplashScreen()
WindowCompat.setDecorFitsSystemWindows(window, false)
+
+ appUpdateManager = AppUpdateManagerFactory.create(this)
+ checkImmediateUpdateAvailability()
+
requestNotificationPermission()
+ BootpayAnalytics.init(this, BuildConfig.BOOTPAY_APPLICATION_ID)
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
@@ -112,21 +202,8 @@ class MainActivity : AppCompatActivity() {
setContent {
val navHostController = rememberNavController()
- var currentScreen by remember { mutableStateOf(BottomScreen.Home.name) }
- var isBottomBarVisible = true
- var isTopBarVisible = true
- val navBackStackEntry = navHostController.currentBackStackEntryAsState()
- navBackStackEntry.value?.destination?.route?.let { route ->
- if (route in bottomNav) {
- currentScreen = route
- }
- isBottomBarVisible = route in needBottomBarScreens
- isTopBarVisible = route in needTopBarScreens
- } ?: run {
- isBottomBarVisible = false
- isTopBarVisible = false
- }
+ val navBackStackEntry by navHostController.currentBackStackEntryAsState()
val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
val deeplink = remember { handleDeeplink(intent) }
@@ -134,28 +211,26 @@ class MainActivity : AppCompatActivity() {
modifier = Modifier.systemBarsPadding(),
backgroundColor = Color.White,
bottomBar = {
- if (isBottomBarVisible) {
- MainBottomBar(
- initValue = currentScreen,
- onClickHome = navHostController::navigateToHome,
- onClickHPedia = navHostController::navigateToHPedia,
- onClickLike = navHostController::navigateToMagazineHome,
- onClickMyPage = navHostController::navigateToUserInfoGraph
- )
- }
+ MainBottomBar(
+ navController = navHostController,
+ needBottomBarScreen = needBottomBarScreens,
+ onClickHome = navHostController::navigateToHome,
+ onClickHPedia = navHostController::navigateToHPedia,
+ onClickLike = navHostController::navigateToMagazineHome,
+ onClickMyPage = navHostController::navigateToUserInfoGraph
+ )
},
scaffoldState = scaffoldState,
topBar = {
- if (isTopBarVisible) {
- HomeTopBar(
- onDrawerClick = { navHostController.navigateToBrandSearch() },
- onSearchClick = { navHostController.navigateToPerfumeSearch() },
- onNotificationClick = { navHostController.navigateToAlarmScreen() },
- drawerIcon = painterResource(com.hmoa.core_designsystem.R.drawable.ic_drawer),
- searchIcon = painterResource(com.hmoa.core_designsystem.R.drawable.ic_search),
- notificationIcon = painterResource(com.hmoa.core_designsystem.R.drawable.ic_bell)
- )
- }
+ HomeTopBar(
+ navBackStackEntry = navBackStackEntry,
+ onDrawerClick = { navHostController.navigateToBrandSearch() },
+ onSearchClick = { navHostController.navigateToPerfumeSearch() },
+ onNotificationClick = { navHostController.navigateToAlarmScreen() },
+ drawerIcon = painterResource(com.hmoa.core_designsystem.R.drawable.ic_drawer),
+ searchIcon = painterResource(com.hmoa.core_designsystem.R.drawable.ic_search),
+ notificationIcon = painterResource(com.hmoa.core_designsystem.R.drawable.ic_bell)
+ )
},
) {
Box(
@@ -177,6 +252,11 @@ class MainActivity : AppCompatActivity() {
}
}
+ override fun onResume() {
+ super.onResume()
+ checkFlexibleUpdateAvailability()
+ }
+
//firebase 초기 토큰 처리
private fun initializeFirebaseSetting(fcmToken: String?, onSaveFcmToken: (token: String) -> Unit) {
FirebaseMessaging.getInstance().token.addOnSuccessListener {
@@ -288,19 +368,4 @@ class MainActivity : AppCompatActivity() {
lifecycleScope.launch { viewModel.saveNotificationEnabled(true) }
}
}
-
- override fun onResume() {
- super.onResume()
- //30분 마다 토큰 재발급하는 임시대책
- val handler = Handler(Looper.getMainLooper())
- val runnable = object : java.lang.Runnable {
- override fun run() {
- // 작업 실행
- Log.d("HandlerTest", "another shot in 1 minute")
- viewModel.refreshToken()
- handler.postDelayed(this, 30 * 60 * 1000) // 30분 후에 다시 실행
- }
- }
- handler.post(runnable)
- }
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/hmoa/app/AppViewModel.kt b/app/src/main/java/com/hmoa/app/viewmodel/AppViewModel.kt
similarity index 93%
rename from app/src/main/java/com/hmoa/app/AppViewModel.kt
rename to app/src/main/java/com/hmoa/app/viewmodel/AppViewModel.kt
index daaaf2b65..6b1adb339 100644
--- a/app/src/main/java/com/hmoa/app/AppViewModel.kt
+++ b/app/src/main/java/com/hmoa/app/viewmodel/AppViewModel.kt
@@ -1,4 +1,4 @@
-package com.hmoa.app
+package com.hmoa.app.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
@@ -7,8 +7,6 @@ import com.hmoa.core_domain.repository.LoginRepository
import com.hmoa.core_model.request.FCMTokenSaveRequestDto
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
@@ -43,4 +41,4 @@ class AppViewModel @Inject constructor(
suspend fun saveNotificationEnabled(isEnabled: Boolean) =
viewModelScope.launch { fcmRepository.saveNotificationEnabled(isEnabled) }
-}
\ No newline at end of file
+}
diff --git a/build.gradle.kts b/build.gradle.kts
index dbd98f21a..188389a47 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,21 +1,19 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
dependencies {
- classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0")
+ classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.21")
classpath("com.google.dagger:hilt-android-gradle-plugin:2.48.1")
classpath("com.google.gms:google-services:4.4.1")
classpath("com.google.android.gms:oss-licenses-plugin:0.10.4")
-
}
}
-
plugins {
- id("com.android.application") version "8.1.0" apply false
- id("org.jetbrains.kotlin.android") version "1.9.0" apply false
- id("org.jetbrains.kotlin.jvm") version "1.9.0" apply false
- id("com.android.library") version "8.1.0" apply false
- id("com.google.dagger.hilt.android") version "2.48.1" apply false
- id("org.jetbrains.kotlin.plugin.serialization") version "1.5.0"
- id("com.google.gms.google-services") version "4.4.1" apply false
-}
\ No newline at end of file
+ alias(libs.plugins.android.application) apply false
+ alias(libs.plugins.kotlin.android) apply false
+ alias(libs.plugins.kotlin.jvm) apply false
+ alias(libs.plugins.android.library) apply false
+ alias(libs.plugins.hilt.android) apply false
+ alias(libs.plugins.kotlin.plugin.serialization) apply false
+ alias(libs.plugins.google.services) apply false
+}
diff --git a/copy-hmoa-android-secrets.sh b/copy-hmoa-android-secrets.sh
index 6c107d1f1..ba3524aad 100755
--- a/copy-hmoa-android-secrets.sh
+++ b/copy-hmoa-android-secrets.sh
@@ -17,6 +17,7 @@ FILE_PATHS=(
"feature-userInfo/local.properties"
"core-network/local.properties"
"feature-authentication/local.properties"
+ "feature-hbti/local.properties"
)
DEST_DIRS=(
"./app"
@@ -24,6 +25,7 @@ DEST_DIRS=(
"./feature-userInfo"
"./core-network"
"./feature-authentication"
+ "./feature-hbti"
)
# 반복문을 통해 파일을 가져와서 복사
diff --git a/core-common/build.gradle.kts b/core-common/build.gradle.kts
index ed4fd5ad1..2eea478dc 100644
--- a/core-common/build.gradle.kts
+++ b/core-common/build.gradle.kts
@@ -1,6 +1,6 @@
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
+ alias(libs.plugins.android.library)
+ alias(libs.plugins.kotlin.android)
}
android {
@@ -32,9 +32,7 @@ android {
dependencies {
implementation(project(":core-model"))
- implementation("androidx.core:core-ktx:1.9.0")
- implementation("androidx.appcompat:appcompat:1.6.1")
- implementation("com.google.android.material:material:1.11.0")
+ implementation(libs.bundles.basic)
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
testImplementation("junit:junit:4.13.2")
diff --git a/core-common/src/main/java/com/hmoa/core_common/CommonFunctions.kt b/core-common/src/main/java/com/hmoa/core_common/CommonFunctions.kt
new file mode 100644
index 000000000..bd28222f2
--- /dev/null
+++ b/core-common/src/main/java/com/hmoa/core_common/CommonFunctions.kt
@@ -0,0 +1,72 @@
+package com.hmoa.core_common
+
+import android.content.Context
+import android.net.Uri
+import com.hmoa.core_model.data.OrderStatus
+import java.io.File
+import java.io.FileOutputStream
+
+fun formatWon(value: Int): String = String.format("%,d", value)
+
+fun concatWithComma(values: List): String {
+ var result = ""
+ values.forEach {
+ result += it
+ if (values.lastIndex != values.indexOf(it)) {
+ result += ", "
+ }
+ }
+ return result
+}
+
+fun calculateProgressStepSize(list: List?): Float {
+ if ((list?.size ?: 0) <= 1) {
+ return 100f
+ } else {
+ return ((100).div(list?.size?.minus(1) ?: 10)).div(100.0).toFloat()
+ }
+}
+
+fun calculateHbtiProgressStepSize(size: Int): Float {
+ val result = 1f.div(size)
+ return result
+}
+
+fun OrderStatus.toDisplayString(): String {
+ return when (this) {
+ OrderStatus.CREATED -> "주문 생성"
+ OrderStatus.PAY_FAILED -> "결제 실패"
+ OrderStatus.PAY_CANCEL -> "환불 완료"
+ OrderStatus.PAY_COMPLETE -> "결제 완료"
+ OrderStatus.RETURN_PROGRESS
+ -> "반품 진행 중"
+
+ OrderStatus.RETURN_COMPLETE -> "반품 완료"
+ OrderStatus.SHIPPING_COMPLETE -> "배송 완료"
+ OrderStatus.SHIPPING_PROGRESS -> "배송 중"
+ OrderStatus.PURCHASE_CONFIRMATION -> "구매 확정"
+ }
+}
+
+//로컬 uri >> File 타입 변경
+fun absolutePath(context: Context, uri: Uri): String? {
+ val contentResolver = context.contentResolver
+
+ val filePath = (context.applicationInfo.dataDir + File.separator + System.currentTimeMillis())
+ val file = File(filePath)
+
+ try {
+ val inputStream = contentResolver.openInputStream(uri) ?: return null
+
+ val outputStream = FileOutputStream(file)
+
+ val buf = ByteArray(1024)
+ var len: Int
+ while (inputStream.read(buf).also { len = it } > 0) outputStream.write(buf, 0, len)
+ outputStream.close()
+ inputStream.close()
+ } catch (ignore: Exception) {
+ return null
+ }
+ return file.absolutePath
+}
diff --git a/core-common/src/main/java/com/hmoa/core_common/ErrorHandleFunctions.kt b/core-common/src/main/java/com/hmoa/core_common/ErrorHandleFunctions.kt
index b369475d4..21a80214f 100644
--- a/core-common/src/main/java/com/hmoa/core_common/ErrorHandleFunctions.kt
+++ b/core-common/src/main/java/com/hmoa/core_common/ErrorHandleFunctions.kt
@@ -3,10 +3,6 @@ package com.hmoa.core_common
import ResultResponse
suspend fun ResultResponse.emitOrThrow(emit: suspend (ResultResponse) -> Unit) {
- android.util.Log.d(
- "core-common/ErrorHandleFunctions",
- "emitOrThrow --- data: ${data}, errorMessage: ${errorMessage?.message}"
- )
if (this.data != null) {
emit(this)
} else if (this.errorMessage != null) {
@@ -32,4 +28,4 @@ fun handleErrorType(
else -> onGeneralError()
}
-}
\ No newline at end of file
+}
diff --git a/core-common/src/main/java/com/hmoa/core_common/ErrorUiState.kt b/core-common/src/main/java/com/hmoa/core_common/ErrorUiState.kt
index fc03467f1..9f62097d2 100644
--- a/core-common/src/main/java/com/hmoa/core_common/ErrorUiState.kt
+++ b/core-common/src/main/java/com/hmoa/core_common/ErrorUiState.kt
@@ -7,7 +7,11 @@ sealed interface ErrorUiState {
val unknownError: Boolean,
val memberNotFoundError: Boolean? = null,
val generalError: Pair
- ) : ErrorUiState
+ ) : ErrorUiState {
+ fun isValidate(): Boolean{
+ return expiredTokenError || wrongTypeTokenError || unknownError || generalError.first
+ }
+ }
data object Loading : ErrorUiState
}
\ No newline at end of file
diff --git a/core-database/build.gradle.kts b/core-database/build.gradle.kts
index 5fbfc16d7..072afe18d 100644
--- a/core-database/build.gradle.kts
+++ b/core-database/build.gradle.kts
@@ -1,8 +1,7 @@
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("dagger.hilt.android.plugin")
- id("com.google.dagger.hilt.android")
+ alias(libs.plugins.android.library)
+ alias(libs.plugins.kotlin.android)
+ alias(libs.plugins.hilt.android)
kotlin("kapt")
}
@@ -44,33 +43,21 @@ android {
}
dependencies {
- val hilt_version = "2.48.1"
- val datastore_version = "1.0.0"
- val room_version = "2.6.1"
+ implementation(project(":core-model"))
- implementation("androidx.room:room-ktx:$room_version")
- kapt("androidx.room:room-compiler:$room_version")
- implementation("com.google.dagger:hilt-android:$hilt_version")
- implementation("com.google.dagger:hilt-compiler:$hilt_version")
- implementation("androidx.datastore:datastore-preferences:$datastore_version")
- implementation("androidx.core:core-ktx:1.9.0")
- implementation("androidx.appcompat:appcompat:1.6.1")
- implementation("com.google.android.material:material:1.11.0")
-
- testAnnotationProcessor("com.google.dagger:hilt-android-compiler:2.44")
+ //room
+ implementation(libs.room.ktx)
+ kapt(libs.room.compiler)
+ implementation(libs.bundles.hilt) //hilt
+ implementation(libs.datastore) //data store
+ implementation(libs.bundles.basic)
- testImplementation("junit:junit:4.13.2")
- implementation("androidx.test.ext:junit-ktx:1.2.1")
//unit test
- val mockito_version = "4.8.0"
- testImplementation("junit:junit:4.13.2")
- debugImplementation("androidx.compose.ui:ui-tooling:1.6.0")
- testImplementation("org.mockito:mockito-core:$mockito_version")
- testImplementation("org.mockito:mockito-inline:$mockito_version")
- testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.5.2")
- testImplementation("org.jetbrains.kotlin:kotlin-reflect:1.5.30")
+ implementation(libs.junit.ktx)
+ testImplementation(libs.junit)
+ testImplementation(libs.bundles.unit.test)
//hilt test
- kaptTest("com.google.dagger:hilt-android-compiler:$hilt_version") // ...with Kotlin.
- testImplementation("com.google.dagger:hilt-android-testing:$hilt_version") // For Robolectric tests.
- testAnnotationProcessor("com.google.dagger:hilt-android-compiler:2.44") // ...with Java.
+ kaptTest(libs.hilt.android.compiler)
+ testImplementation(libs.hilt.android.test) // For Robolectric
+ testAnnotationProcessor(libs.hilt.android.compiler)
}
\ No newline at end of file
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/DatabaseModule.kt b/core-database/src/main/java/com/hmoa/core_database/di/DatabaseModule.kt
similarity index 95%
rename from core-datastore/src/main/java/com/hmoa/core_datastore/DatabaseModule.kt
rename to core-database/src/main/java/com/hmoa/core_database/di/DatabaseModule.kt
index 9cc41de7f..ef46bb4e8 100644
--- a/core-datastore/src/main/java/com/hmoa/core_datastore/DatabaseModule.kt
+++ b/core-database/src/main/java/com/hmoa/core_database/di/DatabaseModule.kt
@@ -1,4 +1,4 @@
-package com.hmoa.core_datastore
+package com.hmoa.core_database.di
import android.content.Context
import androidx.room.Room
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/LocalDataStorePreferenceManagerModule.kt b/core-database/src/main/java/com/hmoa/core_database/di/LocalDataStorePreferenceManagerModule.kt
similarity index 58%
rename from core-datastore/src/main/java/com/hmoa/core_datastore/LocalDataStorePreferenceManagerModule.kt
rename to core-database/src/main/java/com/hmoa/core_database/di/LocalDataStorePreferenceManagerModule.kt
index f2dcdc624..f8527292a 100644
--- a/core-datastore/src/main/java/com/hmoa/core_datastore/LocalDataStorePreferenceManagerModule.kt
+++ b/core-database/src/main/java/com/hmoa/core_database/di/LocalDataStorePreferenceManagerModule.kt
@@ -1,11 +1,8 @@
-package com.hmoa.core_datastore
+package com.hmoa.core_database.di
-import com.hmoa.core_database.AppInfoManager
-import com.hmoa.core_database.AppInfoManagerImpl
-import com.hmoa.core_database.SignupInfoManager
-import com.hmoa.core_database.SignupInfoManagerImpl
-import com.hmoa.core_database.TokenManager
-import com.hmoa.core_database.TokenManagerImpl
+import com.hmoa.core_database.*
+import com.hmoa.core_database.lrucache.PerfumeRecommendCacheManager
+import com.hmoa.core_database.lrucache.PerfumeRecommendCacheManagerImpl
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
@@ -26,5 +23,9 @@ interface LocalDataStorePreferenceManagerModule {
@Binds
@Singleton
- fun bindAppSettingManager(appInfoManagerImpl: AppInfoManagerImpl) : AppInfoManager
+ fun bindAppSettingManager(appInfoManagerImpl: AppInfoManagerImpl): AppInfoManager
+
+ @Binds
+ @Singleton
+ fun bindPerfumeRecommendCacheManager(perfumeRecommendCacheManagerImpl: PerfumeRecommendCacheManagerImpl): PerfumeRecommendCacheManager
}
\ No newline at end of file
diff --git a/core-database/src/main/java/com/hmoa/core_database/lrucache/CacheKey.kt b/core-database/src/main/java/com/hmoa/core_database/lrucache/CacheKey.kt
new file mode 100644
index 000000000..b6652bb75
--- /dev/null
+++ b/core-database/src/main/java/com/hmoa/core_database/lrucache/CacheKey.kt
@@ -0,0 +1,6 @@
+package com.hmoa.core_database.lrucache
+
+enum class CacheKey {
+ PriceSortedPerfumeRecommendsResult,
+ NoteSortedPerfumeRecommendsResult
+}
\ No newline at end of file
diff --git a/core-database/src/main/java/com/hmoa/core_database/lrucache/PerfumeRecommendCacheManager.kt b/core-database/src/main/java/com/hmoa/core_database/lrucache/PerfumeRecommendCacheManager.kt
new file mode 100644
index 000000000..780f0c79c
--- /dev/null
+++ b/core-database/src/main/java/com/hmoa/core_database/lrucache/PerfumeRecommendCacheManager.kt
@@ -0,0 +1,11 @@
+package com.hmoa.core_database.lrucache
+
+import com.hmoa.core_model.response.PerfumeRecommendsResponseDto
+
+interface PerfumeRecommendCacheManager {
+ fun saveNoteSortedPerfumeRecommendsResult(dto: PerfumeRecommendsResponseDto)
+ fun getNoteSortedPerfumeRecommendsResult(): PerfumeRecommendsResponseDto?
+
+ fun savePriceSortedPerfumeRecommendsResult(dto: PerfumeRecommendsResponseDto)
+ fun getPriceSortedPerfumeRecommendsResult(): PerfumeRecommendsResponseDto?
+}
\ No newline at end of file
diff --git a/core-database/src/main/java/com/hmoa/core_database/lrucache/PerfumeRecommendCacheManagerImpl.kt b/core-database/src/main/java/com/hmoa/core_database/lrucache/PerfumeRecommendCacheManagerImpl.kt
new file mode 100644
index 000000000..c3aff727c
--- /dev/null
+++ b/core-database/src/main/java/com/hmoa/core_database/lrucache/PerfumeRecommendCacheManagerImpl.kt
@@ -0,0 +1,26 @@
+package com.hmoa.core_database.lrucache
+
+import android.util.LruCache
+import com.hmoa.core_model.response.PerfumeRecommendsResponseDto
+import javax.inject.Inject
+
+class PerfumeRecommendCacheManagerImpl @Inject constructor() : PerfumeRecommendCacheManager {
+ // 클래스 멤버로 LruCache 선언
+ private val cacheSize = 4 * 1024 * 1024 // 4MB...적당한가??
+ private val perfumeRecommendsResultCache = LruCache(cacheSize)
+ override fun saveNoteSortedPerfumeRecommendsResult(dto: PerfumeRecommendsResponseDto) {
+ perfumeRecommendsResultCache.put(CacheKey.NoteSortedPerfumeRecommendsResult.name, dto)
+ }
+
+ override fun getNoteSortedPerfumeRecommendsResult(): PerfumeRecommendsResponseDto? {
+ return perfumeRecommendsResultCache.get(CacheKey.NoteSortedPerfumeRecommendsResult.name)
+ }
+
+ override fun savePriceSortedPerfumeRecommendsResult(dto: PerfumeRecommendsResponseDto) {
+ perfumeRecommendsResultCache.put(CacheKey.PriceSortedPerfumeRecommendsResult.name, dto)
+ }
+
+ override fun getPriceSortedPerfumeRecommendsResult(): PerfumeRecommendsResponseDto? {
+ return perfumeRecommendsResultCache.get(CacheKey.PriceSortedPerfumeRecommendsResult.name)
+ }
+}
\ No newline at end of file
diff --git a/core-datastore/build.gradle.kts b/core-datastore/build.gradle.kts
index 5faa8e930..edfcc4ee2 100644
--- a/core-datastore/build.gradle.kts
+++ b/core-datastore/build.gradle.kts
@@ -1,8 +1,7 @@
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("dagger.hilt.android.plugin")
- id("com.google.dagger.hilt.android")
+ alias(libs.plugins.android.library)
+ alias(libs.plugins.kotlin.android)
+ alias(libs.plugins.hilt.android)
kotlin("kapt")
}
@@ -33,22 +32,21 @@ android {
}
dependencies {
- val hilt_version = "2.48.1"
- val kotlinx_version = "1.5.0"
- val room_version = "2.6.1"
-
- implementation("androidx.room:room-ktx:$room_version")
- kapt("androidx.room:room-compiler:$room_version")
-
implementation(project(":core-model"))
implementation(project(":core-network"))
implementation(project(":core-database"))
+ val hilt_version = "2.48.1"
+ val kotlinx_version = "1.5.0"
+
+ implementation(libs.room.ktx)
+ kapt(libs.room.compiler)
+
implementation("com.github.skydoves:sandwich:1.3.5")
- implementation("com.google.dagger:hilt-android:$hilt_version")
- implementation("com.google.dagger:hilt-compiler:$hilt_version")
- testAnnotationProcessor("com.google.dagger:hilt-compiler:$hilt_version")
- kapt("com.google.dagger:hilt-android-compiler:$hilt_version")
- implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinx_version")
- implementation("androidx.datastore:datastore-preferences:1.0.0")
+ implementation(libs.sandwich)
+ implementation(libs.bundles.hilt)
+ testAnnotationProcessor(libs.hilt.compiler)
+ kapt(libs.hilt.android.compiler)
+ implementation(libs.kotlinx.serialization.json)
+ implementation(libs.datastore)
}
\ No newline at end of file
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/Bootpay/BootpayDataStore.kt b/core-datastore/src/main/java/com/hmoa/core_datastore/Bootpay/BootpayDataStore.kt
new file mode 100644
index 000000000..d781fd695
--- /dev/null
+++ b/core-datastore/src/main/java/com/hmoa/core_datastore/Bootpay/BootpayDataStore.kt
@@ -0,0 +1,13 @@
+package com.hmoa.core_datastore.Bootpay
+
+import ResultResponse
+import com.hmoa.core_model.request.CancelBootpayRequestDto
+import com.hmoa.core_model.request.ConfirmBootpayRequestDto
+import com.hmoa.core_model.response.BootpayOrderResultData
+import com.hmoa.core_model.response.DataResponseDto
+
+interface BootpayDataStore {
+ suspend fun postConfirm(requestDto: ConfirmBootpayRequestDto): ResultResponse>
+ suspend fun postCancel(requestDto: CancelBootpayRequestDto): ResultResponse>
+ suspend fun deleteOrder(orderId: Int): ResultResponse>
+}
\ No newline at end of file
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/Bootpay/BootpayDataStoreImpl.kt b/core-datastore/src/main/java/com/hmoa/core_datastore/Bootpay/BootpayDataStoreImpl.kt
new file mode 100644
index 000000000..e9d0370a4
--- /dev/null
+++ b/core-datastore/src/main/java/com/hmoa/core_datastore/Bootpay/BootpayDataStoreImpl.kt
@@ -0,0 +1,66 @@
+package com.hmoa.core_datastore.Bootpay
+
+import ResultResponse
+import com.hmoa.core_model.request.CancelBootpayRequestDto
+import com.hmoa.core_model.request.ConfirmBootpayRequestDto
+import com.hmoa.core_model.response.BootpayOrderResultData
+import com.hmoa.core_model.response.DataResponseDto
+import com.hmoa.core_network.authentication.Authenticator
+import com.hmoa.core_network.service.BootpayService
+import com.skydoves.sandwich.message
+import com.skydoves.sandwich.suspendOnError
+import com.skydoves.sandwich.suspendOnSuccess
+import javax.inject.Inject
+
+class BootpayDataStoreImpl @Inject constructor(
+ private val bootpayService: BootpayService,
+ private val authenticator: Authenticator
+): BootpayDataStore {
+ override suspend fun postConfirm(requestDto: ConfirmBootpayRequestDto): ResultResponse> {
+ val result = ResultResponse>()
+ bootpayService.postConfirm(requestDto).suspendOnSuccess{
+ result.data = this.data
+ }.suspendOnError{
+ authenticator.handleApiError(
+ rawMessage = this.message(),
+ handleErrorMesssage = { result.errorMessage = it },
+ onCompleteTokenRefresh = {
+ bootpayService.postConfirm(requestDto).suspendOnSuccess { result.data = this.data }
+ }
+ )
+ }
+ return result
+ }
+
+ override suspend fun postCancel(requestDto: CancelBootpayRequestDto): ResultResponse> {
+ val result = ResultResponse>()
+ bootpayService.postCancel(requestDto).suspendOnSuccess{
+ result.data = this.data
+ }.suspendOnError{
+ authenticator.handleApiError(
+ rawMessage = this.message(),
+ handleErrorMesssage = { result.errorMessage = it },
+ onCompleteTokenRefresh = {
+ bootpayService.postCancel(requestDto).suspendOnSuccess { result.data = this.data }
+ }
+ )
+ }
+ return result
+ }
+
+ override suspend fun deleteOrder(orderId: Int): ResultResponse> {
+ val result = ResultResponse>()
+ bootpayService.deleteOrder(orderId).suspendOnSuccess{
+ result.data = this.data
+ }.suspendOnError{
+ authenticator.handleApiError(
+ rawMessage = this.message(),
+ handleErrorMesssage = { result.errorMessage = it },
+ onCompleteTokenRefresh = {
+ bootpayService.deleteOrder(orderId).suspendOnSuccess { result.data = this.data }
+ }
+ )
+ }
+ return result
+ }
+}
\ No newline at end of file
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/Community/CommunityDataStore.kt b/core-datastore/src/main/java/com/hmoa/core_datastore/Community/CommunityDataStore.kt
index 9180bce2a..c1a78572c 100644
--- a/core-datastore/src/main/java/com/hmoa/core_datastore/Community/CommunityDataStore.kt
+++ b/core-datastore/src/main/java/com/hmoa/core_datastore/Community/CommunityDataStore.kt
@@ -1,7 +1,6 @@
package com.hmoa.core_datastore.Community
import ResultResponse
-import com.hmoa.core_model.Category
import com.hmoa.core_model.response.CommunityByCategoryResponseDto
import com.hmoa.core_model.response.CommunityDefaultResponseDto
import com.hmoa.core_model.response.CommunityWithCursorResponseDto
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/DatastoreModule.kt b/core-datastore/src/main/java/com/hmoa/core_datastore/DatastoreModule.kt
index 8d8c7ddff..51419b773 100644
--- a/core-datastore/src/main/java/com/hmoa/core_datastore/DatastoreModule.kt
+++ b/core-datastore/src/main/java/com/hmoa/core_datastore/DatastoreModule.kt
@@ -1,5 +1,7 @@
package com.hmoa.core_datastore
+import com.hmoa.core_datastore.Bootpay.BootpayDataStore
+import com.hmoa.core_datastore.Bootpay.BootpayDataStoreImpl
import com.hmoa.core_datastore.Brand.BrandDataStore
import com.hmoa.core_datastore.Brand.BrandDataStoreImpl
import com.hmoa.core_datastore.BrandHPedia.BrandHPediaDataStore
@@ -12,6 +14,8 @@ import com.hmoa.core_datastore.Fcm.FcmLocalDataStore
import com.hmoa.core_datastore.Fcm.FcmLocalDataStoreImpl
import com.hmoa.core_datastore.Fcm.FcmRemoteDataStore
import com.hmoa.core_datastore.Fcm.FcmRemoteDataStoreImpl
+import com.hmoa.core_datastore.HShopReview.HShopReviewDataStore
+import com.hmoa.core_datastore.HShopReview.HShopReviewDataStoreImpl
import com.hmoa.core_datastore.Hshop.HshopRemoteDataStore
import com.hmoa.core_datastore.Hshop.HshopRemoteDataStoreImpl
import com.hmoa.core_datastore.Login.LoginLocalDataStore
@@ -141,4 +145,12 @@ interface DatastoreModule {
@Singleton
@Binds
fun provideHshopRemoteDataStore(hshopRemoteDataStoreImpl: HshopRemoteDataStoreImpl): HshopRemoteDataStore
+
+ @Singleton
+ @Binds
+ fun provideBootpayDataStore(bootpayDataStoreImpl: BootpayDataStoreImpl): BootpayDataStore
+
+ @Singleton
+ @Binds
+ fun provideHshopReviewDataStore(hShopReviewDataStoreImpl: HShopReviewDataStoreImpl): HShopReviewDataStore
}
\ No newline at end of file
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/HShopReview/HShopReviewDataStore.kt b/core-datastore/src/main/java/com/hmoa/core_datastore/HShopReview/HShopReviewDataStore.kt
new file mode 100644
index 000000000..63ded35fa
--- /dev/null
+++ b/core-datastore/src/main/java/com/hmoa/core_datastore/HShopReview/HShopReviewDataStore.kt
@@ -0,0 +1,26 @@
+package com.hmoa.core_datastore.HShopReview
+
+import ResultResponse
+import com.hmoa.core_model.response.PagingData
+import com.hmoa.core_model.response.ReviewResponseDto
+import java.io.File
+
+interface HShopReviewDataStore {
+ suspend fun getReviews(page: Int): ResultResponse>
+ suspend fun postReview(
+ image: Array,
+ orderId: Int,
+ content: String,
+ ): ResultResponse
+ suspend fun getReview(reviewId: Int): ResultResponse
+ suspend fun postEditReview(
+ image: Array,
+ deleteReviewPhotoIds: Array,
+ content: String,
+ reviewId: Int
+ ): ResultResponse
+ suspend fun deleteReview(reviewId: Int): ResultResponse
+ suspend fun putReviewLike(reviewId: Int): ResultResponse
+ suspend fun deleteReviewLike(reviewId: Int): ResultResponse
+ suspend fun getMyReviews(cursor: Int): ResultResponse>
+}
\ No newline at end of file
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/HShopReview/HShopReviewDataStoreImpl.kt b/core-datastore/src/main/java/com/hmoa/core_datastore/HShopReview/HShopReviewDataStoreImpl.kt
new file mode 100644
index 000000000..e0e59ad39
--- /dev/null
+++ b/core-datastore/src/main/java/com/hmoa/core_datastore/HShopReview/HShopReviewDataStoreImpl.kt
@@ -0,0 +1,117 @@
+package com.hmoa.core_datastore.HShopReview
+
+import ResultResponse
+import com.hmoa.core_datastore.Mapper.transformRequestBody
+import com.hmoa.core_datastore.Mapper.transformToMultipartBody
+import com.hmoa.core_model.data.ErrorMessage
+import com.hmoa.core_model.response.PagingData
+import com.hmoa.core_model.response.ReviewResponseDto
+import com.hmoa.core_network.service.HShopReviewService
+import com.skydoves.sandwich.message
+import com.skydoves.sandwich.suspendOnError
+import com.skydoves.sandwich.suspendOnSuccess
+import kotlinx.serialization.decodeFromString
+import kotlinx.serialization.json.Json
+import java.io.File
+import javax.inject.Inject
+
+class HShopReviewDataStoreImpl @Inject constructor(
+ private val hShopReviewService: HShopReviewService
+) : HShopReviewDataStore{
+ override suspend fun getReviews(page: Int): ResultResponse> {
+ val result = ResultResponse>()
+ hShopReviewService.getReviews(page).suspendOnError{
+ result.errorMessage = Json.decodeFromString(this.message())
+ }.suspendOnSuccess{
+ result.data = this.data
+ }
+ return result
+ }
+
+ override suspend fun postReview(
+ image: Array,
+ orderId: Int,
+ content: String
+ ): ResultResponse {
+ val result = ResultResponse()
+ hShopReviewService.postReview(
+ image.transformToMultipartBody(),
+ orderId.transformRequestBody(),
+ content.transformRequestBody()
+ ).suspendOnError{
+ result.errorMessage = Json.decodeFromString(this.message())
+ }.suspendOnSuccess{
+ result.data = this.data
+ }
+ return result
+ }
+
+ override suspend fun getReview(reviewId: Int): ResultResponse {
+ val result = ResultResponse()
+ hShopReviewService.getReview(reviewId).suspendOnError{
+ result.errorMessage = Json.decodeFromString(this.message())
+ }.suspendOnSuccess{
+ result.data = this.data
+ }
+ return result
+ }
+
+ override suspend fun postEditReview(
+ image: Array,
+ deleteReviewPhotoIds: Array,
+ content: String,
+ reviewId: Int
+ ): ResultResponse {
+ val result = ResultResponse()
+ hShopReviewService.postEditReview(
+ image.transformToMultipartBody(),
+ deleteReviewPhotoIds.transformRequestBody(),
+ content.transformRequestBody(),
+ reviewId
+ ).suspendOnError{
+ result.errorMessage = Json.decodeFromString(this.message())
+ }.suspendOnSuccess{
+ result.data = this.data
+ }
+ return result
+ }
+
+ override suspend fun deleteReview(reviewId: Int): ResultResponse {
+ val result = ResultResponse()
+ hShopReviewService.deleteReview(reviewId).suspendOnError{
+ result.errorMessage = Json.decodeFromString(this.message())
+ }.suspendOnSuccess{
+ result.data = this.data
+ }
+ return result
+ }
+
+ override suspend fun putReviewLike(reviewId: Int): ResultResponse {
+ val result = ResultResponse()
+ hShopReviewService.putReviewLike(reviewId).suspendOnError{
+ result.errorMessage = Json.decodeFromString(this.message())
+ }.suspendOnSuccess{
+ result.data = this.data
+ }
+ return result
+ }
+
+ override suspend fun deleteReviewLike(reviewId: Int): ResultResponse {
+ val result = ResultResponse()
+ hShopReviewService.deleteReviewLike(reviewId).suspendOnError{
+ result.errorMessage = Json.decodeFromString(this.message())
+ }.suspendOnSuccess{
+ result.data = this.data
+ }
+ return result
+ }
+ override suspend fun getMyReviews(cursor: Int): ResultResponse> {
+ val result = ResultResponse>()
+ hShopReviewService.getMyReviews(cursor).suspendOnError{
+ result.errorMessage = Json.decodeFromString(this.message())
+ }.suspendOnSuccess{
+ result.data = this.data
+ }
+ return result
+ }
+}
\ No newline at end of file
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/Hshop/HshopRemoteDataStore.kt b/core-datastore/src/main/java/com/hmoa/core_datastore/Hshop/HshopRemoteDataStore.kt
index ed99a1d50..831de8adf 100644
--- a/core-datastore/src/main/java/com/hmoa/core_datastore/Hshop/HshopRemoteDataStore.kt
+++ b/core-datastore/src/main/java/com/hmoa/core_datastore/Hshop/HshopRemoteDataStore.kt
@@ -2,9 +2,15 @@ package com.hmoa.core_datastore.Hshop
import ResultResponse
import com.hmoa.core_model.request.ProductListRequestDto
-import com.hmoa.core_model.response.ProductListResponseDto
+import com.hmoa.core_model.response.*
interface HshopRemoteDataStore {
+ suspend fun getCart(): ResultResponse
suspend fun getNotes(): ResultResponse
- suspend fun postNotesSelected(dto: ProductListRequestDto): ResultResponse
-}
\ No newline at end of file
+ suspend fun postNoteOrder(dto: ProductListRequestDto): ResultResponse
+ suspend fun postNotesSelected(dto: ProductListRequestDto): ResultResponse
+ suspend fun getFinalOrderResult(orderId: Int): ResultResponse
+ suspend fun deleteNoteInOrder(orderId: Int, productId: Int): ResultResponse
+ suspend fun getMyOrders(): ResultResponse>
+ suspend fun getOrderDescriptions(): ResultResponse
+}
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/Hshop/HshopRemoteDataStoreImpl.kt b/core-datastore/src/main/java/com/hmoa/core_datastore/Hshop/HshopRemoteDataStoreImpl.kt
index 3c269657f..cbddadf2c 100644
--- a/core-datastore/src/main/java/com/hmoa/core_datastore/Hshop/HshopRemoteDataStoreImpl.kt
+++ b/core-datastore/src/main/java/com/hmoa/core_datastore/Hshop/HshopRemoteDataStoreImpl.kt
@@ -1,48 +1,108 @@
package com.hmoa.core_datastore.Hshop
import ResultResponse
+import com.hmoa.core_model.data.ErrorMessage
import com.hmoa.core_model.request.ProductListRequestDto
-import com.hmoa.core_model.response.ProductListResponseDto
+import com.hmoa.core_model.response.*
import com.hmoa.core_network.authentication.Authenticator
import com.hmoa.core_network.service.HshopService
import com.skydoves.sandwich.message
import com.skydoves.sandwich.suspendOnError
import com.skydoves.sandwich.suspendOnSuccess
+import kotlinx.serialization.json.Json
import javax.inject.Inject
class HshopRemoteDataStoreImpl @Inject constructor(
private val hshopService: HshopService,
private val authenticator: Authenticator
) : HshopRemoteDataStore {
+ override suspend fun getCart(): ResultResponse {
+ val result = ResultResponse()
+ hshopService.getCart().suspendOnSuccess {
+ result.data = this.data
+ }.suspendOnError {
+ result.errorMessage = Json.decodeFromString(this.message())
+ }
+ return result
+ }
+
override suspend fun getNotes(): ResultResponse {
var result = ResultResponse()
hshopService.getNotes().suspendOnSuccess {
result.data = this.data
}.suspendOnError {
- authenticator.handleApiError(
- rawMessage = this.message(),
- handleErrorMesssage = { result.errorMessage = it },
- onCompleteTokenRefresh = {
- hshopService.getNotes().suspendOnSuccess { result.data = this.data }
- }
- )
+ val errorMessage = Json.decodeFromString(this.message())
+ result.errorMessage = errorMessage
}
return result
}
- override suspend fun postNotesSelected(dto: ProductListRequestDto): ResultResponse {
- val result = ResultResponse()
+ override suspend fun postNoteOrder(dto: ProductListRequestDto): ResultResponse {
+ val result = ResultResponse()
+ hshopService.postNoteOrder(dto).suspendOnSuccess {
+ result.data = this.data
+ }.suspendOnError {
+ result.errorMessage = Json.decodeFromString(this.message())
+ }
+ return result
+ }
+
+ override suspend fun postNotesSelected(dto: ProductListRequestDto): ResultResponse {
+ val result = ResultResponse()
hshopService.postNotesSelected(dto).suspendOnSuccess {
result.data = this.data
+ }.suspendOnError {
+ val errorMessage = Json.decodeFromString(this.message())
+ result.errorMessage = errorMessage
+ }
+ return result
+ }
+
+ override suspend fun getFinalOrderResult(orderId: Int): ResultResponse {
+ val result = ResultResponse()
+ hshopService.getFinalOrderResult(orderId).suspendOnSuccess {
+ result.data = this.data
+ }.suspendOnError {
+ result.errorMessage = Json.decodeFromString(this.message())
+ }
+ return result
+ }
+
+ override suspend fun deleteNoteInOrder(
+ orderId: Int,
+ productId: Int
+ ): ResultResponse {
+ val result = ResultResponse()
+ hshopService.deleteNoteInOrder(orderId, productId).suspendOnSuccess {
+ result.data = this.data
+ }.suspendOnError {
+ result.errorMessage = Json.decodeFromString(this.message())
+ }
+ return result
+ }
+
+ override suspend fun getMyOrders(): ResultResponse> {
+ val result = ResultResponse>()
+ hshopService.getMyOrders().suspendOnError {
+ result.errorMessage = Json.decodeFromString(this.message())
+ }.suspendOnSuccess {
+ result.data = this.data
+ }
+ return result
+ }
+
+ override suspend fun getOrderDescriptions(): ResultResponse {
+ val result = ResultResponse()
+ hshopService.getOrderDescriptions().suspendOnSuccess {
+ result.data = this.data
}.suspendOnError {
authenticator.handleApiError(
rawMessage = this.message(),
handleErrorMesssage = { result.errorMessage = it },
onCompleteTokenRefresh = {
- hshopService.postNotesSelected(dto).suspendOnSuccess { result.data = this.data }
- }
- )
+ hshopService.getOrderDescriptions().suspendOnSuccess { result.data = this.data }
+ })
}
return result
}
-}
\ No newline at end of file
+}
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/Login/LoginRemoteDataStore.kt b/core-datastore/src/main/java/com/hmoa/core_datastore/Login/LoginRemoteDataStore.kt
index 4fa49307a..92a04ec56 100644
--- a/core-datastore/src/main/java/com/hmoa/core_datastore/Login/LoginRemoteDataStore.kt
+++ b/core-datastore/src/main/java/com/hmoa/core_datastore/Login/LoginRemoteDataStore.kt
@@ -13,5 +13,4 @@ interface LoginRemoteDataStore {
suspend fun postOAuth(accessToken: OauthLoginRequestDto, provider: Provider): ResultResponse
suspend fun postRemembered(dto: RememberedLoginRequestDto): ResultResponse
suspend fun postGoogleServerAuthCode(dto: GoogleAccessTokenRequestDto): ResultResponse
- suspend fun refreshToken()
}
\ No newline at end of file
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/Mapper/IntToMultipartBody.kt b/core-datastore/src/main/java/com/hmoa/core_datastore/Mapper/IntToMultipartBody.kt
index 6f25129a6..a4d91a0a9 100644
--- a/core-datastore/src/main/java/com/hmoa/core_datastore/Mapper/IntToMultipartBody.kt
+++ b/core-datastore/src/main/java/com/hmoa/core_datastore/Mapper/IntToMultipartBody.kt
@@ -24,4 +24,8 @@ fun Array.transformRequestBody() : Array {
fun Int.transformMultipartBody() : MultipartBody.Part {
val result = this.toString().toRequestBody("multipart/form-data".toMediaTypeOrNull())
return MultipartBody.Part.createFormData("deleteCommunityPhotoIds", null, result)
+}
+
+fun Int.transformRequestBody(): RequestBody{
+ return this.toString().transformRequestBody()
}
\ No newline at end of file
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/Member/MemberDataStore.kt b/core-datastore/src/main/java/com/hmoa/core_datastore/Member/MemberDataStore.kt
index 70034ae96..ccbbda29c 100644
--- a/core-datastore/src/main/java/com/hmoa/core_datastore/Member/MemberDataStore.kt
+++ b/core-datastore/src/main/java/com/hmoa/core_datastore/Member/MemberDataStore.kt
@@ -1,6 +1,8 @@
package com.hmoa.core_datastore.Member
import ResultResponse
+import com.hmoa.core_model.data.DefaultAddressDto
+import com.hmoa.core_model.data.DefaultOrderInfoDto
import com.hmoa.core_model.request.AgeRequestDto
import com.hmoa.core_model.request.JoinUpdateRequestDto
import com.hmoa.core_model.request.NickNameRequestDto
@@ -8,12 +10,17 @@ import com.hmoa.core_model.request.SexRequestDto
import com.hmoa.core_model.response.CommunityByCategoryResponseDto
import com.hmoa.core_model.response.CommunityCommentDefaultResponseDto
import com.hmoa.core_model.response.DataResponseDto
+import com.hmoa.core_model.response.GetRefundRecordResponseDto
import com.hmoa.core_model.response.MemberResponseDto
+import com.hmoa.core_model.response.OrderRecordDto
+import com.hmoa.core_model.response.PagingData
import java.io.File
interface MemberDataStore {
suspend fun getMember(): ResultResponse
- suspend fun updateAge(request: AgeRequestDto): DataResponseDto
+ suspend fun getAddress(): ResultResponse
+ suspend fun postAddress(request: DefaultAddressDto): ResultResponse>
+ suspend fun updateAge(request: AgeRequestDto): ResultResponse>
suspend fun getCommunities(page: Int): ResultResponse>
suspend fun getCommunityComments(page: Int): ResultResponse>
suspend fun getCommunityFavoriteComments(page: Int): ResultResponse>
@@ -21,9 +28,13 @@ interface MemberDataStore {
suspend fun postExistsNickname(request: NickNameRequestDto): ResultResponse
suspend fun updateJoin(request: JoinUpdateRequestDto): ResultResponse
suspend fun updateNickname(request: NickNameRequestDto): ResultResponse>
+ suspend fun getOrder(cursor: Int): ResultResponse>
+ suspend fun getRefundRecord(cursor: Int): ResultResponse>
+ suspend fun getOrderInfo(): ResultResponse
+ suspend fun postOrderInfo(request: DefaultOrderInfoDto): ResultResponse>
suspend fun getPerfumeComments(page: Int): ResultResponse>
suspend fun getPerfumeFavoriteComments(page: Int): ResultResponse>
suspend fun postProfilePhoto(image: File): ResultResponse>
suspend fun deleteProfilePhoto(): DataResponseDto
- suspend fun updateSex(request: SexRequestDto): DataResponseDto
+ suspend fun updateSex(request: SexRequestDto): ResultResponse>
}
\ No newline at end of file
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/Member/MemberDataStoreImpl.kt b/core-datastore/src/main/java/com/hmoa/core_datastore/Member/MemberDataStoreImpl.kt
index 3e253362a..324758189 100644
--- a/core-datastore/src/main/java/com/hmoa/core_datastore/Member/MemberDataStoreImpl.kt
+++ b/core-datastore/src/main/java/com/hmoa/core_datastore/Member/MemberDataStoreImpl.kt
@@ -2,6 +2,9 @@ package com.hmoa.core_datastore.Member
import ResultResponse
import com.hmoa.core_datastore.Mapper.transformToMultipartBody
+import com.hmoa.core_model.data.DefaultAddressDto
+import com.hmoa.core_model.data.DefaultOrderInfoDto
+import com.hmoa.core_model.data.ErrorMessage
import com.hmoa.core_model.request.AgeRequestDto
import com.hmoa.core_model.request.JoinUpdateRequestDto
import com.hmoa.core_model.request.NickNameRequestDto
@@ -9,13 +12,18 @@ import com.hmoa.core_model.request.SexRequestDto
import com.hmoa.core_model.response.CommunityByCategoryResponseDto
import com.hmoa.core_model.response.CommunityCommentDefaultResponseDto
import com.hmoa.core_model.response.DataResponseDto
+import com.hmoa.core_model.response.GetRefundRecordResponseDto
import com.hmoa.core_model.response.MemberResponseDto
+import com.hmoa.core_model.response.OrderRecordDto
+import com.hmoa.core_model.response.PagingData
import com.hmoa.core_network.authentication.Authenticator
import com.hmoa.core_network.service.MemberService
import com.skydoves.sandwich.message
import com.skydoves.sandwich.suspendMapSuccess
import com.skydoves.sandwich.suspendOnError
import com.skydoves.sandwich.suspendOnSuccess
+import kotlinx.serialization.decodeFromString
+import kotlinx.serialization.json.Json
import java.io.File
import javax.inject.Inject
@@ -39,9 +47,47 @@ class MemberDataStoreImpl @Inject constructor(
}
return result
}
+ override suspend fun getAddress(): ResultResponse {
+ val result = ResultResponse()
+ memberService.getAddress().suspendOnSuccess{
+ result.data = this.data
+ }.suspendOnError{
+ val errorMessage = Json.decodeFromString(this.message())
+ result.errorMessage = errorMessage
+ }
+ return result
+ }
+
+ override suspend fun postAddress(request: DefaultAddressDto): ResultResponse> {
+ val result = ResultResponse>()
+ memberService.postAddress(request).suspendOnSuccess{
+ result.data = this.data
+ }.suspendOnError{
+ authenticator.handleApiError(
+ rawMessage = this.message(),
+ handleErrorMesssage = { result.errorMessage = it },
+ onCompleteTokenRefresh = {
+ memberService.postAddress(request).suspendOnSuccess { result.data = this.data }
+ }
+ )
+ }
+ return result
+ }
- override suspend fun updateAge(request: AgeRequestDto): DataResponseDto {
- return memberService.updateAge(request)
+ override suspend fun updateAge(request: AgeRequestDto): ResultResponse> {
+ val result = ResultResponse>()
+ memberService.updateAge(request).suspendOnSuccess{
+ result.data = this.data
+ }.suspendOnError{
+ authenticator.handleApiError(
+ rawMessage = this.message(),
+ handleErrorMesssage = { result.errorMessage = it },
+ onCompleteTokenRefresh = {
+ memberService.updateAge(request).suspendOnSuccess { result.data = this.data }
+ }
+ )
+ }
+ return result
}
override suspend fun getCommunities(page: Int): ResultResponse> {
@@ -86,19 +132,15 @@ class MemberDataStoreImpl @Inject constructor(
val result = ResultResponse()
memberService.postExistsNickname(request)
.suspendOnSuccess {
- result.data = false
+ result.data = this.data
}.suspendOnError {
- if (this.statusCode.code == 409) {
- result.data = true
- } else {
- authenticator.handleApiError(
- rawMessage = this.message(),
- handleErrorMesssage = { result.errorMessage = it },
- onCompleteTokenRefresh = {
- memberService.postExistsNickname(request).suspendOnSuccess { result.data = this.data }
- }
- )
- }
+ authenticator.handleApiError(
+ rawMessage = this.message(),
+ handleErrorMesssage = { result.errorMessage = it },
+ onCompleteTokenRefresh = {
+ memberService.postExistsNickname(request).suspendOnSuccess { result.data = this.data }
+ }
+ )
}
return result
}
@@ -137,6 +179,70 @@ class MemberDataStoreImpl @Inject constructor(
return result
}
+ override suspend fun getOrder(cursor: Int): ResultResponse> {
+ val result = ResultResponse>()
+ memberService.getOrder(cursor).suspendOnSuccess{
+ result.data = this.data
+ }.suspendOnError{
+ authenticator.handleApiError(
+ rawMessage = this.message(),
+ handleErrorMesssage = { result.errorMessage = it },
+ onCompleteTokenRefresh = {
+ memberService.getOrder(cursor).suspendOnSuccess { result.data = this.data }
+ }
+ )
+ }
+ return result
+ }
+
+ override suspend fun getRefundRecord(cursor: Int): ResultResponse> {
+ val result = ResultResponse>()
+ memberService.getRefundRecord(cursor).suspendOnSuccess{
+ result.data = this.data
+ }.suspendOnError{
+ authenticator.handleApiError(
+ rawMessage = this.message(),
+ handleErrorMesssage = { result.errorMessage = it },
+ onCompleteTokenRefresh = {
+ memberService.getRefundRecord(cursor).suspendOnSuccess { result.data = this.data }
+ }
+ )
+ }
+ return result
+ }
+
+ override suspend fun getOrderInfo(): ResultResponse {
+ val result = ResultResponse()
+ memberService.getOrderInfo().suspendOnSuccess{
+ result.data = this.data
+ }.suspendOnError{
+ authenticator.handleApiError(
+ rawMessage = this.message(),
+ handleErrorMesssage = { result.errorMessage = it },
+ onCompleteTokenRefresh = {
+ memberService.getOrderInfo().suspendOnSuccess { result.data = this.data }
+ }
+ )
+ }
+ return result
+ }
+
+ override suspend fun postOrderInfo(request: DefaultOrderInfoDto): ResultResponse> {
+ val result = ResultResponse>()
+ memberService.postOrderInfo(request).suspendOnSuccess{
+ result.data = this.data
+ }.suspendOnError{
+ authenticator.handleApiError(
+ rawMessage = this.message(),
+ handleErrorMesssage = { result.errorMessage = it },
+ onCompleteTokenRefresh = {
+ memberService.postOrderInfo(request).suspendOnSuccess { result.data = this.data }
+ }
+ )
+ }
+ return result
+ }
+
override suspend fun getCommunityFavoriteComments(page: Int): ResultResponse> {
val result = ResultResponse>()
memberService.getCommunityFavoriteComments(page)
@@ -210,7 +316,19 @@ class MemberDataStoreImpl @Inject constructor(
return memberService.deleteProfilePhoto()
}
- override suspend fun updateSex(request: SexRequestDto): DataResponseDto {
- return memberService.updateSex(request)
+ override suspend fun updateSex(request: SexRequestDto): ResultResponse> {
+ val result = ResultResponse>()
+ memberService.updateSex(request).suspendOnSuccess {
+ result.data = this.data
+ }.suspendOnError {
+ authenticator.handleApiError(
+ rawMessage = this.message(),
+ handleErrorMesssage = { result.errorMessage = it },
+ onCompleteTokenRefresh = {
+ memberService.updateSex(request).suspendOnSuccess { result.data = this.data }
+ }
+ )
+ }
+ return result
}
-}
\ No newline at end of file
+}
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/Report/ReportDataStore.kt b/core-datastore/src/main/java/com/hmoa/core_datastore/Report/ReportDataStore.kt
index f394ea78d..52c07fd99 100644
--- a/core-datastore/src/main/java/com/hmoa/core_datastore/Report/ReportDataStore.kt
+++ b/core-datastore/src/main/java/com/hmoa/core_datastore/Report/ReportDataStore.kt
@@ -6,6 +6,7 @@ import com.hmoa.core_model.response.DataResponseDto
interface ReportDataStore {
suspend fun reportPerfumeComment(dto: TargetRequestDto): ResultResponse>
- suspend fun reportCommunity(dto: TargetRequestDto): DataResponseDto
- suspend fun reportCommunityComment(dto: TargetRequestDto): DataResponseDto
- }
\ No newline at end of file
+ suspend fun reportCommunity(dto: TargetRequestDto): ResultResponse>
+ suspend fun reportCommunityComment(dto: TargetRequestDto): ResultResponse>
+ suspend fun reportReview(reviewId: Int): ResultResponse>
+}
\ No newline at end of file
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/Report/ReportDataStoreImpl.kt b/core-datastore/src/main/java/com/hmoa/core_datastore/Report/ReportDataStoreImpl.kt
index 42232e170..da2b95874 100644
--- a/core-datastore/src/main/java/com/hmoa/core_datastore/Report/ReportDataStoreImpl.kt
+++ b/core-datastore/src/main/java/com/hmoa/core_datastore/Report/ReportDataStoreImpl.kt
@@ -1,6 +1,7 @@
package com.hmoa.core_datastore.Report
import ResultResponse
+import com.hmoa.core_model.data.ErrorMessage
import com.hmoa.core_model.request.TargetRequestDto
import com.hmoa.core_model.response.DataResponseDto
import com.hmoa.core_network.authentication.Authenticator
@@ -8,21 +9,47 @@ import com.hmoa.core_network.service.ReportService
import com.skydoves.sandwich.message
import com.skydoves.sandwich.suspendOnError
import com.skydoves.sandwich.suspendOnSuccess
+import kotlinx.serialization.decodeFromString
+import kotlinx.serialization.json.Json
import javax.inject.Inject
class ReportDataStoreImpl @Inject constructor(
private val reportService: ReportService,
private val authenticator: Authenticator
) : ReportDataStore {
- override suspend fun reportCommunity(dto: TargetRequestDto): DataResponseDto {
- return reportService.postReportCommunity(dto)
+ override suspend fun reportCommunity(dto: TargetRequestDto): ResultResponse> {
+ val result = ResultResponse>()
+ reportService.postReportCommunity(dto).suspendOnError{
+ authenticator.handleApiError(
+ rawMessage = this.message(),
+ handleErrorMesssage = { result.errorMessage = it },
+ onCompleteTokenRefresh = {
+ reportService.postReportCommunityComment(dto).suspendOnSuccess { result.data = this.data }
+ }
+ )
+ }.suspendOnSuccess{
+ result.data = this.data
+ }
+ return result
}
- override suspend fun reportCommunityComment(dto: TargetRequestDto): DataResponseDto {
- return reportService.postReportCommunityComment(dto)
+ override suspend fun reportCommunityComment(dto: TargetRequestDto): ResultResponse> {
+ val result = ResultResponse>()
+ reportService.postReportCommunityComment(dto).suspendOnError{
+ authenticator.handleApiError(
+ rawMessage = this.message(),
+ handleErrorMesssage = { result.errorMessage = it },
+ onCompleteTokenRefresh = {
+ reportService.postReportCommunityComment(dto).suspendOnSuccess { result.data = this.data }
+ }
+ )
+ }.suspendOnSuccess{
+ result.data = this.data
+ }
+ return result
}
- suspend override fun reportPerfumeComment(dto: TargetRequestDto): ResultResponse> {
+ override suspend fun reportPerfumeComment(dto: TargetRequestDto): ResultResponse> {
val result = ResultResponse>()
reportService.postReportPerfumeComment(dto).suspendOnSuccess {
result.data = this.data
@@ -37,4 +64,14 @@ class ReportDataStoreImpl @Inject constructor(
}
return result
}
+
+ override suspend fun reportReview(reviewId: Int): ResultResponse> {
+ val result = ResultResponse>()
+ reportService.postReportReview(reviewId).suspendOnError{
+ result.errorMessage = Json.decodeFromString(this.message())
+ }.suspendOnSuccess{
+ result.data = this.data
+ }
+ return result
+ }
}
\ No newline at end of file
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/Survey/SurveyLocalDataStore.kt b/core-datastore/src/main/java/com/hmoa/core_datastore/Survey/SurveyLocalDataStore.kt
index 18f74631b..44d02c655 100644
--- a/core-datastore/src/main/java/com/hmoa/core_datastore/Survey/SurveyLocalDataStore.kt
+++ b/core-datastore/src/main/java/com/hmoa/core_datastore/Survey/SurveyLocalDataStore.kt
@@ -1,6 +1,8 @@
package com.hmoa.core_datastore.Survey
+import ResultResponse
import com.hmoa.core_model.request.NoteResponseDto
+import com.hmoa.core_model.response.PerfumeRecommendsResponseDto
interface SurveyLocalDataStore {
@@ -9,6 +11,10 @@ interface SurveyLocalDataStore {
suspend fun updateSurveyResult(note: NoteResponseDto)
suspend fun deleteSurveyResult(note: NoteResponseDto)
-
suspend fun deleteAllNotes()
+ fun saveNoteSortedPerfumeRecommendsResult(dto: PerfumeRecommendsResponseDto)
+ fun getNoteSortedPerfumeRecommendsResult(): ResultResponse
+
+ fun savePriceSortedPerfumeRecommendsResult(dto: PerfumeRecommendsResponseDto)
+ fun getPriceSortedPerfumeRecommendsResult(): ResultResponse
}
\ No newline at end of file
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/Survey/SurveyLocalDataStoreImpl.kt b/core-datastore/src/main/java/com/hmoa/core_datastore/Survey/SurveyLocalDataStoreImpl.kt
index 73de56b72..3ea60de71 100644
--- a/core-datastore/src/main/java/com/hmoa/core_datastore/Survey/SurveyLocalDataStoreImpl.kt
+++ b/core-datastore/src/main/java/com/hmoa/core_datastore/Survey/SurveyLocalDataStoreImpl.kt
@@ -1,12 +1,18 @@
package com.hmoa.core_datastore.Survey
+import ResultResponse
+import com.hmoa.core_database.lrucache.PerfumeRecommendCacheManager
import com.hmoa.core_database.room.NoteDao
import com.hmoa.core_datastore.mapToNote
import com.hmoa.core_datastore.mapToRoomDBNote
import com.hmoa.core_model.request.NoteResponseDto
+import com.hmoa.core_model.response.PerfumeRecommendsResponseDto
import javax.inject.Inject
-class SurveyLocalDataStoreImpl @Inject constructor(private val noteDao: NoteDao) : SurveyLocalDataStore {
+class SurveyLocalDataStoreImpl @Inject constructor(
+ private val noteDao: NoteDao,
+ private val perfumeRecommendCacheManager: PerfumeRecommendCacheManager
+) : SurveyLocalDataStore {
override suspend fun getAllSurveyResult(): List {
return noteDao.getAllNotes().map { mapToNote(it) }
}
@@ -26,4 +32,30 @@ class SurveyLocalDataStoreImpl @Inject constructor(private val noteDao: NoteDao)
override suspend fun deleteAllNotes() {
noteDao.deleteAllNotes()
}
+
+ override fun saveNoteSortedPerfumeRecommendsResult(dto: PerfumeRecommendsResponseDto) {
+ perfumeRecommendCacheManager.saveNoteSortedPerfumeRecommendsResult(dto)
+ }
+
+ override fun getNoteSortedPerfumeRecommendsResult(): ResultResponse {
+ var result = ResultResponse()
+ val data = perfumeRecommendCacheManager.getNoteSortedPerfumeRecommendsResult()
+ if (data != null) {
+ result.data = data
+ }
+ return result
+ }
+
+ override fun savePriceSortedPerfumeRecommendsResult(dto: PerfumeRecommendsResponseDto) {
+ perfumeRecommendCacheManager.savePriceSortedPerfumeRecommendsResult(dto)
+ }
+
+ override fun getPriceSortedPerfumeRecommendsResult(): ResultResponse {
+ var result = ResultResponse()
+ val data = perfumeRecommendCacheManager.getPriceSortedPerfumeRecommendsResult()
+ if (data != null) {
+ result.data = data
+ }
+ return result
+ }
}
\ No newline at end of file
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/Survey/SurveyRemoteDataStore.kt b/core-datastore/src/main/java/com/hmoa/core_datastore/Survey/SurveyRemoteDataStore.kt
index 584c23fd5..4f0dd99f6 100644
--- a/core-datastore/src/main/java/com/hmoa/core_datastore/Survey/SurveyRemoteDataStore.kt
+++ b/core-datastore/src/main/java/com/hmoa/core_datastore/Survey/SurveyRemoteDataStore.kt
@@ -1,19 +1,23 @@
package com.hmoa.core_datastore.Survey
import ResultResponse
-import com.hmoa.core_model.request.ContentRequestDto
-import com.hmoa.core_model.request.SurveyRespondRequestDto
-import com.hmoa.core_model.request.SurveySaveAnswerRequestDtos
-import com.hmoa.core_model.request.SurveySaveRequestDto
-import com.hmoa.core_model.response.DataResponseDto
-import com.hmoa.core_model.response.RecommendNotesResponseDto
-import com.hmoa.core_model.response.SurveyQuestionsResponseDto
+import com.hmoa.core_model.PerfumeRecommendType
+import com.hmoa.core_model.request.*
+import com.hmoa.core_model.response.*
interface SurveyRemoteDataStore {
suspend fun getSurveyQuestions(): ResultResponse
suspend fun postSurveyResponds(dto: SurveyRespondRequestDto): ResultResponse
- suspend fun saveSurvey(dto : SurveySaveRequestDto): ResultResponse>
+ suspend fun saveSurvey(dto: SurveySaveRequestDto): ResultResponse>
suspend fun saveAnswerNote(dto: SurveySaveAnswerRequestDtos): ResultResponse>
suspend fun saveAnswerByQuestionId(dto: ContentRequestDto, questionId: Int): ResultResponse>
suspend fun saveQuestionBySurveyId(dto: ContentRequestDto, surveyId: Int): ResultResponse>
+
+ suspend fun getPerfumeSurvey(): ResultResponse
+ suspend fun postPerfumeSurveyAnswers(
+ dto: PerfumeSurveyAnswerRequestDto,
+ recommendType: PerfumeRecommendType
+ ): ResultResponse
+
+ suspend fun getHbtiHomeMetaDataResult(): ResultResponse
}
\ No newline at end of file
diff --git a/core-datastore/src/main/java/com/hmoa/core_datastore/Survey/SurveyRemoteDataStoreImpl.kt b/core-datastore/src/main/java/com/hmoa/core_datastore/Survey/SurveyRemoteDataStoreImpl.kt
index 84d6e7fa7..22bf5a1fc 100644
--- a/core-datastore/src/main/java/com/hmoa/core_datastore/Survey/SurveyRemoteDataStoreImpl.kt
+++ b/core-datastore/src/main/java/com/hmoa/core_datastore/Survey/SurveyRemoteDataStoreImpl.kt
@@ -1,20 +1,19 @@
package com.hmoa.core_datastore.Survey
import ResultResponse
-import com.hmoa.core_model.request.ContentRequestDto
-import com.hmoa.core_model.request.SurveyRespondRequestDto
-import com.hmoa.core_model.request.SurveySaveAnswerRequestDtos
-import com.hmoa.core_model.request.SurveySaveRequestDto
-import com.hmoa.core_model.response.DataResponseDto
-import com.hmoa.core_model.response.RecommendNotesResponseDto
-import com.hmoa.core_model.response.SurveyQuestionsResponseDto
+import com.hmoa.core_model.PerfumeRecommendType
+import com.hmoa.core_model.data.ErrorMessage
+import com.hmoa.core_model.request.*
+import com.hmoa.core_model.response.*
import com.hmoa.core_network.authentication.Authenticator
import com.hmoa.core_network.service.SurveyService
import com.skydoves.sandwich.message
import com.skydoves.sandwich.suspendOnError
import com.skydoves.sandwich.suspendOnSuccess
+import kotlinx.serialization.json.Json
import javax.inject.Inject
+
class SurveyRemoteDataStoreImpl @Inject constructor(
private val surveyService: SurveyService,
private val authenticator: Authenticator
@@ -120,4 +119,51 @@ class SurveyRemoteDataStoreImpl @Inject constructor(
}
return result
}
-}
\ No newline at end of file
+
+ override suspend fun getPerfumeSurvey(): ResultResponse {
+ val result = ResultResponse()
+ surveyService.getPerfumeSurvey().suspendOnSuccess {
+ result.data = this.data
+ }.suspendOnError {
+ result.errorMessage = Json.decodeFromString(this.message())
+ }
+ return result
+ }
+
+ override suspend fun postPerfumeSurveyAnswers(
+ dto: PerfumeSurveyAnswerRequestDto,
+ recommendType: PerfumeRecommendType
+ ): ResultResponse {
+ val result = ResultResponse()
+ surveyService.postPerfumeSurveyAnswer(dto, recommendType.name).suspendOnSuccess {
+ result.data = this.data
+ }.suspendOnError {
+ authenticator.handleApiError(
+ rawMessage = this.message(),
+ handleErrorMesssage = { result.errorMessage = it },
+ onCompleteTokenRefresh = {
+ surveyService.postPerfumeSurveyAnswer(dto, recommendType.name)
+ .suspendOnSuccess { result.data = this.data }
+ }
+ )
+ }
+ return result
+ }
+
+ override suspend fun getHbtiHomeMetaDataResult(): ResultResponse {
+ val result = ResultResponse()
+ surveyService.getHbtiHomeMetaData().suspendOnSuccess {
+ result.data = this.data
+ }.suspendOnError {
+ authenticator.handleApiError(
+ rawMessage = this.message(),
+ handleErrorMesssage = { result.errorMessage = it },
+ onCompleteTokenRefresh = {
+ surveyService.getHbtiHomeMetaData()
+ .suspendOnSuccess { result.data = this.data }
+ }
+ )
+ }
+ return result
+ }
+}
diff --git a/core-designsystem/build.gradle.kts b/core-designsystem/build.gradle.kts
index 13bd0f291..788eff70a 100644
--- a/core-designsystem/build.gradle.kts
+++ b/core-designsystem/build.gradle.kts
@@ -1,6 +1,6 @@
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
+ alias(libs.plugins.android.library)
+ alias(libs.plugins.kotlin.android)
}
android {
@@ -28,7 +28,7 @@ android {
jvmTarget = "17"
}
composeOptions {
- kotlinCompilerExtensionVersion = "1.5.0"
+ kotlinCompilerExtensionVersion = "1.5.7"
}
buildFeatures {
compose = true
@@ -37,30 +37,20 @@ android {
dependencies {
implementation(project(":core-common"))
- //material3
- implementation("androidx.compose.material3:material3:1.2.1")
+ implementation(project(":core-model"))
- //preview
- implementation("androidx.compose.ui:ui-tooling-preview")
+ implementation(libs.bundles.ui)
+ implementation(libs.navigation.compose)
- implementation("androidx.compose.ui:ui:1.1.0")
-
- //bottom navigation
- implementation("androidx.navigation:navigation-compose:2.7.0")
-
- //coil 라이브러리
- implementation("com.github.skydoves:landscapist-glide:1.4.7")
- implementation("io.coil-kt:coil-gif:2.6.0")
- implementation("io.coil-kt:coil-compose:2.6.0")
+ implementation(libs.bundles.glide) //glide
+ implementation(libs.bundles.coil) //coil
//paging 라이브러리
- implementation("com.google.accompanist:accompanist-pager:0.20.0")
+ implementation(libs.accommpanist.pager)
- implementation("com.github.bumptech.glide:glide:4.16.0")
- implementation("androidx.core:core-ktx:1.9.0")
- implementation("androidx.appcompat:appcompat:1.6.1")
- testImplementation("junit:junit:4.13.2")
- androidTestImplementation("androidx.test.ext:junit:1.1.5")
- androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
- debugImplementation("androidx.compose.ui:ui-tooling:1.6.0")
-}
\ No newline at end of file
+ implementation(libs.bundles.basic)
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.junit.ext)
+ androidTestImplementation(libs.espresso)
+ debugImplementation(libs.ui.tooling)
+}
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/AppDesignDialog.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/AppDesignDialog.kt
index 2111b0ce7..625052980 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/AppDesignDialog.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/AppDesignDialog.kt
@@ -3,11 +3,24 @@ package com.hmoa.core_designsystem.component
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Text
-import androidx.compose.runtime.*
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@@ -28,6 +41,7 @@ fun AppDesignDialog(
modifier: Modifier,
title: String,
buttonTitle: String,
+ buttonColor: Color = CustomColor.gray3,
content: String,
onOkClick: () -> Unit,
onCloseClick: () -> Unit,
@@ -75,9 +89,8 @@ fun AppDesignDialog(
modifier = Modifier
.fillMaxWidth()
.height(48.dp)
- .clickable {
- onOkClick()
- }.background(color = CustomColor.gray3),
+ .clickable {onOkClick()}
+ .background(color = buttonColor),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
@@ -126,6 +139,7 @@ fun TestNavigateDialog() {
content = "테스트 성공",
onOkClick = { isOpen = false },
buttonTitle = "취소",
+ buttonColor = Color.Black,
onCloseClick = { isOpen = false }
)
}
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/BottomCameraBtn.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/BottomCameraBtn.kt
index 93a0ea450..9919d3946 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/BottomCameraBtn.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/BottomCameraBtn.kt
@@ -1,5 +1,9 @@
package com.hmoa.core_designsystem.component
+import android.net.Uri
+import androidx.activity.compose.rememberLauncherForActivityResult
+import androidx.activity.result.PickVisualMediaRequest
+import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxHeight
@@ -10,14 +14,24 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.hmoa.core_designsystem.R
@Composable
fun BottomCameraBtn(
- onClick: () -> Unit,
+ isColorInverted: Boolean = true,
+ onUpdatePictures : (List) -> Unit,
){
+ //갤러리에서 사진 가져오기
+ val multiplePhotoPickerLauncher = rememberLauncherForActivityResult(
+ contract = ActivityResultContracts.PickMultipleVisualMedia(),
+ onResult = {uris ->
+ onUpdatePictures(uris)
+ }
+ )
+
Row(
modifier = Modifier
.fillMaxWidth()
@@ -27,11 +41,18 @@ fun BottomCameraBtn(
modifier = Modifier
.fillMaxHeight()
.aspectRatio(1f),
- onClick = onClick
+ onClick = {
+ multiplePhotoPickerLauncher.launch(
+ PickVisualMediaRequest(
+ ActivityResultContracts.PickVisualMedia.ImageOnly
+ )
+ )
+ }
){
Icon(
modifier = Modifier.fillMaxSize(),
painter = painterResource(R.drawable.ic_camera),
+ tint = if(isColorInverted) Color.Black else Color.White,
contentDescription = "Add Picture"
)
}
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/Button.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/Button.kt
index 1423882e9..7ff08acc5 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/Button.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/Button.kt
@@ -33,7 +33,12 @@ fun Button(
modifier = Modifier
.background(
color = if (isEnabled) Color.Black else CustomColor.gray2,
- shape = RoundedCornerShape(roundCorner)
+ shape = RoundedCornerShape(
+ topStart = roundCorner.dp,
+ topEnd = roundCorner.dp,
+ bottomStart = roundCorner.dp,
+ bottomEnd = roundCorner.dp
+ )
)
.clickable {
if (isEnabled) {
@@ -61,7 +66,7 @@ fun Button(
}
}
-@Preview(showBackground = true)
+@Preview
@Composable
fun TestBottomButton() {
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/Comment.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/Comment.kt
index e60f03877..8b78dfc3e 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/Comment.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/Comment.kt
@@ -6,7 +6,7 @@ import androidx.compose.foundation.layout.*
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
+import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@@ -30,17 +30,19 @@ fun Comment(
comment: String,
isFirst: Boolean,
isSelected: Boolean,
- onChangeSelect: () -> Unit,
heartCount: Int,
+ onHeartClick: (Boolean) -> Unit,
onOpenBottomDialog: () -> Unit,
- onNavCommunity: () -> Unit,
+ navCommunity: () -> Unit,
) {
+ var isLiked by remember { mutableStateOf(isSelected) }
+ var heartCount by remember { mutableStateOf(heartCount) }
Column(
modifier = Modifier
.fillMaxWidth()
.background(color = Color.White)
.clickable {
- onNavCommunity()
+ navCommunity()
}
.padding(horizontal = 16.dp)
.padding(bottom = 16.dp)
@@ -48,6 +50,7 @@ fun Comment(
Spacer(Modifier.height(11.dp))
Row(
+ modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
CircleImageView(imgUrl = profile, width = 28, height = 28)
@@ -90,12 +93,16 @@ fun Comment(
) {
if (isEditable) {
IconButton(
- onClick = onChangeSelect
+ onClick = {
+ if (isLiked) heartCount-- else heartCount++
+ onHeartClick(isLiked)
+ isLiked = !isLiked
+ }
) {
Icon(
modifier = Modifier.size(22.dp),
painter = painterResource(R.drawable.ic_heart_selectable_not_selected),
- tint = if (isSelected) CustomColor.red else CustomColor.gray2,
+ tint = if (isLiked) CustomColor.red else CustomColor.gray2,
contentDescription = "Comment Like Button"
)
}
@@ -153,9 +160,9 @@ fun TestComment() {
comment = "아ㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏㅏ",
isFirst = true,
isSelected = true,
- onChangeSelect = {},
+ onHeartClick = {},
heartCount = 10,
onOpenBottomDialog = {},
- onNavCommunity = {},
+ navCommunity = {},
)
}
\ No newline at end of file
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/CustomOutlinedTextField.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/CustomOutlinedTextField.kt
new file mode 100644
index 000000000..9f4175c93
--- /dev/null
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/CustomOutlinedTextField.kt
@@ -0,0 +1,75 @@
+package com.hmoa.core_designsystem.component
+
+import androidx.compose.foundation.border
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.text.BasicTextField
+import androidx.compose.foundation.text.KeyboardOptions
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.onFocusChanged
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.TextUnit
+import com.hmoa.core_designsystem.theme.CustomColor
+import com.hmoa.core_designsystem.theme.CustomFont
+
+@Composable
+fun CustomOutlinedTextField(
+ modifier: Modifier,
+ value: String,
+ onValueChanged: (value: String) -> Unit,
+ fontSize: TextUnit,
+ enabled: Boolean = true,
+ color: Color = Color.Black,
+ fontFamily: FontFamily,
+ placeHolder: String? = null,
+ borderWidth: Dp,
+ borderColor: Color,
+ borderShape: Shape,
+ padding: PaddingValues,
+ keyboardOptions: KeyboardOptions = KeyboardOptions.Default
+){
+ var isFocused by remember{mutableStateOf(false)}
+ BasicTextField(
+ modifier = modifier.border(width = borderWidth, color = borderColor, shape = borderShape)
+ .padding(paddingValues = padding)
+ .onFocusChanged {isFocused = it.isFocused},
+ value = value,
+ onValueChange = onValueChanged,
+ textStyle = TextStyle(
+ color = color,
+ fontSize = fontSize,
+ fontFamily = fontFamily
+ ),
+ enabled = enabled,
+ singleLine = true,
+ maxLines = 1,
+ decorationBox = {
+ Row(
+ verticalAlignment = Alignment.CenterVertically
+ ){
+ if (!isFocused && placeHolder != null && value.isEmpty()){
+ Text(
+ text = placeHolder,
+ fontSize = fontSize,
+ color = CustomColor.gray1,
+ fontFamily = CustomFont.medium
+ )
+ }
+ it()
+ }
+ },
+ keyboardOptions = keyboardOptions
+ )
+}
\ No newline at end of file
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/EmptyDataPage.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/EmptyDataPage.kt
new file mode 100644
index 000000000..da3fb74e2
--- /dev/null
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/EmptyDataPage.kt
@@ -0,0 +1,42 @@
+package com.hmoa.core_designsystem.component
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.hmoa.core_designsystem.R
+import com.hmoa.core_designsystem.theme.CustomFont
+
+@Composable
+fun EmptyDataPage(mainText: String){
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(bottom = 40.dp),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Center
+ ){
+ Image(
+ modifier = Modifier.size(110.dp),
+ painter = painterResource(R.drawable.ic_app_default_1),
+ contentDescription = "App Logo"
+ )
+ Spacer(Modifier.height(24.dp))
+ Text(
+ text = mainText,
+ fontSize = 22.sp,
+ fontFamily = CustomFont.bold,
+ )
+ }
+}
\ No newline at end of file
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/FloatingActionBtn.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/FloatingActionBtn.kt
index 6fe9c1774..96ebfa0b1 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/FloatingActionBtn.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/FloatingActionBtn.kt
@@ -1,6 +1,7 @@
package com.hmoa.core_designsystem.component
import androidx.compose.foundation.background
+import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
@@ -13,8 +14,8 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.shape.CircleShape
-import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon
@@ -31,8 +32,11 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpOffset
+import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.hmoa.core_designsystem.R
@@ -40,27 +44,34 @@ import com.hmoa.core_designsystem.theme.pretendard
@Composable
fun FloatingActionBtn(
- onNavRecommend: () -> Unit,
- onNavPresent: () -> Unit,
- onNavFree: () -> Unit,
+ isFabOpen: Boolean,
+ onFabClick: (Boolean) -> Unit,
+ width: Dp,
+ fontSize: TextUnit,
+ options: List,
+ events: List<() -> Unit>,
isAvailable: Boolean,
) {
-
- var isOpen by remember { mutableStateOf(false) }
-
+ val itemHeight = when(fontSize){
+ 16.sp -> 40
+ 12.sp -> 35
+ else -> 30
+ }
+ val height = options.size * itemHeight
val textStyle = TextStyle(
color = Color.White,
- fontSize = 16.sp,
+ fontSize = fontSize,
fontFamily = pretendard,
fontWeight = FontWeight.Normal
)
Column(
- modifier = Modifier.width(135.dp)
+ modifier = Modifier.width(width)
) {
Row(
modifier = Modifier
.fillMaxWidth()
+ .background(color = Color.Transparent)
.padding(end = 8.dp),
horizontalArrangement = Arrangement.End
) {
@@ -68,9 +79,10 @@ fun FloatingActionBtn(
modifier = Modifier
.size(56.dp)
.clip(CircleShape)
- .clickable { if (isAvailable) isOpen = !isOpen }
- .background(color = Color.White, shape = CircleShape),
- painter = painterResource(if (isOpen) R.drawable.ic_fab_open else R.drawable.ic_fab),
+ .clickable { if (isAvailable) onFabClick(!isFabOpen) }
+ .background(color = Color.White, shape = CircleShape)
+ .border(width = 1.dp, color = Color.Black, shape = CircleShape),
+ painter = painterResource(if (isFabOpen) R.drawable.ic_fab_open else R.drawable.ic_fab),
contentDescription = "FAB"
)
}
@@ -79,73 +91,58 @@ fun FloatingActionBtn(
DropdownMenu(
modifier = Modifier
- .height(138.dp)
- .width(135.dp)
- .background(color = Color.Black, shape = RoundedCornerShape(10.dp)),
- expanded = isOpen,
- onDismissRequest = {
- isOpen = false
- },
- offset = DpOffset(x = 0.dp, y = (-204).dp)
+ .wrapContentHeight()
+ .width(width)
+ .background(color = Color.Black),
+ expanded = isFabOpen,
+ onDismissRequest = {onFabClick(false)},
+ offset = DpOffset(x = 0.dp, y = (-(90 + height)).dp)
) {
- DropdownMenuItem(
- text = {
- Text(
- modifier = Modifier.height(46.dp),
- text = "추천",
- style = textStyle
- )
- },
- onClick = {
- isOpen = false
- onNavRecommend()
- }
- )
- DropdownMenuItem(
- text = {
- Text(
- modifier = Modifier.height(46.dp),
- text = "시향기",
- style = textStyle
+ repeat(options.size){ idx ->
+ Row(
+ modifier = Modifier.height(itemHeight.dp),
+ verticalAlignment = Alignment.CenterVertically
+ ){
+ DropdownMenuItem(
+ text = {
+ Text(
+ modifier = Modifier.fillMaxWidth(),
+ text = options[idx],
+ style = textStyle,
+ textAlign = TextAlign.Center
+ )
+ },
+ onClick = {
+ onFabClick(false)
+ events[idx]()
+ }
)
- },
- onClick = {
- isOpen = false
- onNavPresent()
}
- )
- DropdownMenuItem(
- text = {
- Text(
- modifier = Modifier.height(46.dp),
- text = "자유",
- style = textStyle
- )
- },
- onClick = {
- isOpen = false
- onNavFree()
- }
- )
+ }
}
}
-
}
@Preview(showBackground = true)
@Composable
fun TestFAB() {
+ var isFabOpen by remember{mutableStateOf(false)}
Box(
modifier = Modifier
.fillMaxSize()
- .background(color = Color.White),
+ .background(color = Color.Black),
contentAlignment = Alignment.Center
) {
FloatingActionBtn(
- onNavRecommend = {},
- onNavPresent = {},
- onNavFree = {},
+ options = listOf("추천", "시향기", "자유"),
+// options = listOf("후기 작성하기 (시트러스 24.10.08)"),
+// options = listOf("추천", "시향기"),
+ events = listOf(),
isAvailable = true,
+ width = 135.dp,
+ fontSize = 16.sp,
+ isFabOpen = isFabOpen,
+ onFabClick = {isFabOpen = it}
)
}
}
\ No newline at end of file
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/HmoaLogoLoading.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/HmoaLogoLoading.kt
new file mode 100644
index 000000000..22b097a16
--- /dev/null
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/HmoaLogoLoading.kt
@@ -0,0 +1,55 @@
+package com.hmoa.core_designsystem.component
+
+import android.os.Build
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.width
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import coil.ImageLoader
+import coil.compose.rememberAsyncImagePainter
+import coil.decode.GifDecoder
+import coil.decode.ImageDecoderDecoder
+import com.hmoa.core_designsystem.R
+
+@Composable
+fun HmoaLogoLoading() {
+ val context = LocalContext.current
+ val imageLoader = ImageLoader.Builder(context)
+ .components {
+ if (Build.VERSION.SDK_INT >= 28) {
+ add(ImageDecoderDecoder.Factory())
+ } else {
+ add(GifDecoder.Factory())
+ }
+ }
+ .build()
+ val painter = rememberAsyncImagePainter(
+ model = R.drawable.hmoa,
+ imageLoader = imageLoader
+ )
+ Box(
+ modifier = Modifier
+ .background(color = Color.Transparent),
+ contentAlignment = Alignment.Center
+ ) {
+ Image(
+ modifier = Modifier.width(230.dp).height(230.dp),
+ painter = painter,
+ contentDescription = "Hmoa logo gif"
+ )
+ }
+}
+
+@Preview
+@Composable
+fun HmoaLogoLoadingPreview() {
+ HmoaLogoLoading()
+}
\ No newline at end of file
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/HomeTopBar.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/HomeTopBar.kt
index 85779bcc1..352a607d2 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/HomeTopBar.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/HomeTopBar.kt
@@ -1,25 +1,36 @@
package com.hmoa.core_designsystem.component
import androidx.compose.foundation.Image
-import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
import androidx.compose.material3.Icon
-import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
+import androidx.navigation.NavBackStackEntry
+import androidx.navigation.compose.currentBackStackEntryAsState
+import androidx.navigation.compose.rememberNavController
import com.hmoa.core_designsystem.R
@Composable
fun HomeTopBar(
+ navBackStackEntry: NavBackStackEntry?,
onDrawerClick: () -> Unit = {},
onSearchClick: () -> Unit = {},
onNotificationClick: () -> Unit = {},
@@ -27,57 +38,75 @@ fun HomeTopBar(
searchIcon: Painter,
notificationIcon: Painter,
) {
- Row(
- modifier = Modifier
- .fillMaxWidth()
- .height(60.dp)
- .padding(16.dp),
- verticalAlignment = Alignment.CenterVertically,
- horizontalArrangement = Arrangement.SpaceBetween
- ) {
- Icon(
- modifier = Modifier.clickable { onDrawerClick() }.size(20.dp),
- painter = drawerIcon,
- contentDescription = "Drawer Button"
- )
-
- Row{
- Image(
- modifier = Modifier.size(15.dp),
- painter = painterResource(R.drawable.ic_alphabet_h),
- contentDescription = null,
- )
- Spacer(modifier = Modifier.padding(end= 14.dp))
- Image(
- modifier = Modifier.size(15.dp),
- painter = painterResource(R.drawable.ic_alphabet_m),
- contentDescription = null,
- )
- Spacer(modifier = Modifier.padding(end= 14.dp))
- Image(
- modifier = Modifier.size(15.dp),
- painter = painterResource(R.drawable.ic_alphabet_o),
- contentDescription = null,
- )
- Spacer(modifier = Modifier.padding(end= 14.dp))
- Image(
- modifier = Modifier.size(15.dp),
- painter = painterResource(R.drawable.ic_alphabet_a),
- contentDescription = null,
- )
+ var currentRoute by remember{ mutableStateOf(null) }
+ val isVisibleTopBar by remember{derivedStateOf {
+ currentRoute == "Home"
+ }}
+ LaunchedEffect(navBackStackEntry?.destination?.route){
+ if (navBackStackEntry?.destination?.route != null){
+ currentRoute = navBackStackEntry.destination.route
}
-
- Row(verticalAlignment = Alignment.CenterVertically) {
- Icon(
- modifier = Modifier.clickable { onSearchClick() }.padding(end = 24.dp).size(20.dp),
- painter = searchIcon,
- contentDescription = "Search Button",
- )
+ }
+ if(isVisibleTopBar){
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(60.dp)
+ .padding(16.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.SpaceBetween
+ ) {
Icon(
- modifier = Modifier.clickable { onNotificationClick() }.size(24.dp),
- painter = notificationIcon,
- contentDescription = "Notification Button"
+ modifier = Modifier
+ .clickable { onDrawerClick() }
+ .size(20.dp),
+ painter = drawerIcon,
+ contentDescription = "Drawer Button"
)
+
+ Row{
+ Image(
+ modifier = Modifier.size(15.dp),
+ painter = painterResource(R.drawable.ic_alphabet_h),
+ contentDescription = null,
+ )
+ Spacer(modifier = Modifier.padding(end= 14.dp))
+ Image(
+ modifier = Modifier.size(15.dp),
+ painter = painterResource(R.drawable.ic_alphabet_m),
+ contentDescription = null,
+ )
+ Spacer(modifier = Modifier.padding(end= 14.dp))
+ Image(
+ modifier = Modifier.size(15.dp),
+ painter = painterResource(R.drawable.ic_alphabet_o),
+ contentDescription = null,
+ )
+ Spacer(modifier = Modifier.padding(end= 14.dp))
+ Image(
+ modifier = Modifier.size(15.dp),
+ painter = painterResource(R.drawable.ic_alphabet_a),
+ contentDescription = null,
+ )
+ }
+
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ Icon(
+ modifier = Modifier
+ .clickable { onSearchClick() }
+ .padding(end = 24.dp)
+ .size(20.dp),
+ painter = searchIcon,
+ contentDescription = "Search Button",
+ )
+ Icon(
+ modifier = Modifier
+ .clickable { onNotificationClick() }
+ .size(24.dp),
+ painter = notificationIcon,
+ contentDescription = "Notification Button"
+ )
+ }
}
}
}
@@ -85,7 +114,9 @@ fun HomeTopBar(
@Preview
@Composable
fun HomeTopBarPreview() {
+ val navBackStackEntry by rememberNavController().currentBackStackEntryAsState()
HomeTopBar(
+ navBackStackEntry = navBackStackEntry,
onDrawerClick = { },
onSearchClick = {},
onNotificationClick = {},
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/LikeRowlistItem.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/LikeRowlistItem.kt
index 5c546496e..d4b7b1630 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/LikeRowlistItem.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/LikeRowlistItem.kt
@@ -3,7 +3,18 @@ package com.hmoa.core_designsystem.component
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
@@ -13,11 +24,10 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@@ -31,7 +41,8 @@ fun LikeRowItem(
itemNameKo: String,
itemNameEng: String,
onClickClose: () -> Unit,
- onNavPerfumeDesc: () -> Unit,
+ isCloseButtonExist: Boolean = true,
+ navPerfume: () -> Unit,
) {
Column(
modifier = Modifier
@@ -39,19 +50,9 @@ fun LikeRowItem(
.width(280.dp)
.background(color = Color.White, shape = RoundedCornerShape(size = 5.dp))
.border(width = 1.dp, color = Color.Black, shape = RoundedCornerShape(size = 5.dp))
- .shadow(
- elevation = 8.dp,
- spotColor = Color(0x26000000),
- ambientColor = Color(0x26000000)
- )
- .shadow(
- elevation = 4.dp,
- spotColor = Color(0x33000000),
- ambientColor = Color(0x33000000)
- ).clickable {
- onNavPerfumeDesc()
- },
+ .clickable {navPerfume()},
horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.SpaceBetween
) {
Row(
modifier = Modifier
@@ -62,15 +63,17 @@ fun LikeRowItem(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
- IconButton(
- modifier = Modifier.size(16.dp),
- onClick = onClickClose
- ) {
- Icon(
- imageVector = Icons.Filled.Close,
- contentDescription = "Close Button",
- tint = Color.White
- )
+ if (isCloseButtonExist) {
+ IconButton(
+ modifier = Modifier.size(16.dp),
+ onClick = onClickClose
+ ) {
+ Icon(
+ imageVector = Icons.Filled.Close,
+ contentDescription = "Close Button",
+ tint = Color.White
+ )
+ }
}
Spacer(Modifier.weight(1f))
@@ -88,49 +91,63 @@ fun LikeRowItem(
Spacer(Modifier.width(16.dp))
}
- Spacer(Modifier.weight(1f))
- Box(
- modifier = Modifier.size(120.dp)
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Bottom,
+ modifier = Modifier.fillMaxWidth().fillMaxHeight(0.8f).background(color = Color.White)
) {
- ImageView(
- imageUrl = itemPicture,
- width = 1f,
- height = 1f,
- backgroundColor = Color.White,
- contentScale = ContentScale.Fit
- )
+ Box(
+ modifier = Modifier.fillMaxSize(0.6f).background(color = Color.White)
+ ) {
+ ImageView(
+ imageUrl = itemPicture,
+ width = 1f,
+ height = 1f,
+ backgroundColor = Color.White,
+ contentScale = ContentScale.Fit
+ )
+ }
+ Spacer(Modifier.height(20.dp))
+ Column(
+ horizontalAlignment = Alignment.Start,
+ modifier = Modifier.fillMaxWidth().padding(horizontal = 24.dp)
+ ) {
+ Text(
+ text = itemNameKo,
+ fontSize = 14.sp,
+ fontWeight = FontWeight.Normal,
+ fontFamily = pretendard,
+ lineHeight = 14.sp,
+ color = Color.Black,
+ overflow = TextOverflow.Ellipsis,
+ maxLines = 2
+ )
+
+ Spacer(Modifier.height(8.dp))
+
+ Text(
+ text = itemNameEng,
+ fontSize = 12.sp,
+ lineHeight = 12.sp,
+ fontWeight = FontWeight.Normal,
+ fontFamily = pretendard,
+ color = Color.Black,
+ overflow = TextOverflow.Ellipsis,
+ maxLines = 2
+ )
+ }
}
- Spacer(Modifier.height(20.dp))
+
Column(
modifier = Modifier
.fillMaxWidth()
- .padding(horizontal = 24.dp)
+ .padding(horizontal = 24.dp).padding(bottom = 24.dp)
+ .background(color = Color.White),
+ verticalArrangement = Arrangement.Top
) {
- Text(
- text = itemNameKo,
- fontSize = 14.sp,
- fontWeight = FontWeight.Normal,
- fontFamily = pretendard,
- lineHeight = 14.sp,
- color = Color.Black
- )
-
- Spacer(Modifier.height(8.dp))
-
- Text(
- text = itemNameEng,
- fontSize = 12.sp,
- lineHeight = 12.sp,
- fontWeight = FontWeight.Normal,
- fontFamily = pretendard,
- color = Color.Black
- )
-
- Spacer(Modifier.height(28.dp))
-
Row(
- modifier = Modifier.fillMaxWidth(),
- horizontalArrangement = Arrangement.SpaceBetween
+ modifier = Modifier.fillMaxWidth().background(color = Color.White),
+ horizontalArrangement = Arrangement.SpaceBetween,
) {
Text(
text = "Price",
@@ -146,10 +163,36 @@ fun LikeRowItem(
lineHeight = 14.sp,
fontWeight = FontWeight.Normal,
fontFamily = pretendard,
- color = Color.Black
+ color = Color.Black,
)
}
}
- Spacer(Modifier.weight(1f))
}
}
+
+@Preview
+@Composable
+fun LikeRowItemPreview() {
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ LikeRowItem(
+ brand = "조말론",
+ itemPicture = "?",
+ price = "50000",
+ itemNameKo = "우드 세이지 앤 씨 솔트 코롱",
+ itemNameEng = "Wood Sage & Sea Salt Cologne",
+ onClickClose = {},
+ navPerfume = {},
+ isCloseButtonExist = false
+ )
+ LikeRowItem(
+ brand = "구찌",
+ itemPicture = "?",
+ price = "50000",
+ itemNameKo = "[단종] 플로라 바이 구찌 오 드 퍼퓸",
+ itemNameEng = "[Discontinued] Flora by Gucci Eau de Parfum",
+ onClickClose = {},
+ navPerfume = {},
+ isCloseButtonExist = false
+ )
+ }
+}
\ No newline at end of file
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/MainBottomBar.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/MainBottomBar.kt
index c3698fa58..21523c2c0 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/MainBottomBar.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/MainBottomBar.kt
@@ -1,5 +1,6 @@
package com.hmoa.core_designsystem.component
+import android.util.Log
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -11,6 +12,12 @@ import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@@ -19,6 +26,9 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
+import androidx.navigation.NavHostController
+import androidx.navigation.compose.currentBackStackEntryAsState
+import androidx.navigation.compose.rememberNavController
import com.hmoa.core_designsystem.BottomNavItem
import com.hmoa.core_designsystem.BottomScreen
import com.hmoa.core_designsystem.R
@@ -26,69 +36,87 @@ import com.hmoa.core_designsystem.theme.pretendard
@Composable
fun MainBottomBar(
- initValue : String,
+ navController: NavHostController,
+ needBottomBarScreen: List,
onClickHome: () -> Unit,
onClickHPedia: () -> Unit,
onClickLike: () -> Unit,
onClickMyPage: () -> Unit
) {
+ val bottomNav = listOf(
+ BottomScreen.Home.name,
+ BottomScreen.HPedia.name,
+ BottomScreen.Magazine.name,
+ BottomScreen.MyPage.name
+ )
+ var currentScreen by remember{mutableStateOf(bottomNav[0])}
+ val isVisibleBottomBar by remember{derivedStateOf{
+ currentScreen in needBottomBarScreen
+ }}
+ val navBackStackEntry by navController.currentBackStackEntryAsState()
+ LaunchedEffect(navBackStackEntry?.destination?.route){
+ if (navBackStackEntry != null && navBackStackEntry!!.destination.route != null){
+ currentScreen = navBackStackEntry!!.destination.route!!
+ }
+ Log.d("TAG TEST", "current route: ${currentScreen}")
+ }
val bottomNavItems = listOf(
BottomNavItem(
name = BottomScreen.Home,
route = onClickHome,
- icon = if(initValue == "Home") painterResource(R.drawable.ic_nav_home_selected)
+ icon = if(currentScreen == "Home") painterResource(R.drawable.ic_nav_home_selected)
else painterResource(R.drawable.ic_home)
),
BottomNavItem(
name = BottomScreen.HPedia,
route = onClickHPedia,
- icon = if (initValue == "HPedia") painterResource(R.drawable.ic_nav_hpedia_selected)
+ icon = if (currentScreen == "HPedia") painterResource(R.drawable.ic_nav_hpedia_selected)
else painterResource(R.drawable.ic_hpedia)
),
BottomNavItem(
name = BottomScreen.Magazine,
route = onClickLike,
- icon = if (initValue == "Magazine") painterResource(R.drawable.ic_magazine_selected)
+ icon = if (currentScreen == "Magazine") painterResource(R.drawable.ic_magazine_selected)
else painterResource(R.drawable.ic_magazine_not_selected)
),
BottomNavItem(
name = BottomScreen.MyPage,
route = onClickMyPage,
- icon = if (initValue == "MyPage") painterResource(R.drawable.ic_nav_my_page_selected)
+ icon = if (currentScreen == "MyPage") painterResource(R.drawable.ic_nav_my_page_selected)
else painterResource(R.drawable.ic_person)
),
)
- NavigationBar(containerColor = Color.Black) {
- Row(
- verticalAlignment = Alignment.CenterVertically
- ){
- bottomNavItems.forEach{item ->
- NavigationBarItem(
- selected = false,
- onClick = {
- item.route()
- },
- icon = {
- Column(
- verticalArrangement = Arrangement.Center,
- horizontalAlignment = Alignment.CenterHorizontally
- ){
- Icon(
- modifier = Modifier.size(25.dp),
- painter = item.icon,
- contentDescription = "${item.name}아이템",
- tint = Color.White
- )
+ if (isVisibleBottomBar){
+ NavigationBar(containerColor = Color.Black) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically
+ ){
+ bottomNavItems.forEach{ item ->
+ NavigationBarItem(
+ selected = false,
+ onClick = { item.route() },
+ icon = {
+ Column(
+ verticalArrangement = Arrangement.Center,
+ horizontalAlignment = Alignment.CenterHorizontally
+ ){
+ Icon(
+ modifier = Modifier.size(25.dp),
+ painter = item.icon,
+ contentDescription = "${item.name}아이템",
+ tint = Color.White
+ )
- Spacer(Modifier.height(5.dp))
+ Spacer(Modifier.height(5.dp))
- if (initValue == item.name.name) {
- Text(text = item.name.name, fontSize = 12.sp, fontWeight = FontWeight.Medium, fontFamily = pretendard, color = Color.White)
+ if (currentScreen == item.name.name) {
+ Text(text = item.name.name, fontSize = 12.sp, fontWeight = FontWeight.Medium, fontFamily = pretendard, color = Color.White)
+ }
}
}
- }
- )
+ )
+ }
}
}
}
@@ -98,5 +126,11 @@ fun MainBottomBar(
@Composable
fun MainBottomBarPreview() {
var selectedScreen = BottomScreen.Home.name
- MainBottomBar(selectedScreen, {selectedScreen = BottomScreen.Home.name}, {selectedScreen = BottomScreen.HPedia.name}, {}, {})
+ val needBottomBarScreens = listOf()
+// val navBackStackEntry by rememberNavController().currentBackStackEntryAsState()
+ MainBottomBar(
+ rememberNavController(),
+ needBottomBarScreen = needBottomBarScreens,
+ {selectedScreen = BottomScreen.Home.name},
+ {selectedScreen = BottomScreen.HPedia.name}, {}, {})
}
\ No newline at end of file
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/NicknameInput.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/NicknameInput.kt
index 1d9325281..66d943dc3 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/NicknameInput.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/NicknameInput.kt
@@ -1,12 +1,27 @@
package com.hmoa.core_designsystem.component
+import android.util.Log
+import androidx.compose.foundation.background
import androidx.compose.foundation.border
-import androidx.compose.foundation.layout.*
-import androidx.compose.material3.Divider
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
-import androidx.compose.runtime.*
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@@ -16,20 +31,19 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.hmoa.core_designsystem.theme.CustomColor
+import com.hmoa.core_designsystem.theme.CustomFont
import com.hmoa.core_designsystem.theme.pretendard
@Composable
fun NicknameInput(
initNickname : String? = null,
- onChangeValue : (String) -> Unit = {},
onPressNicknameExist: (text: String) -> Unit,
- isAvailable: Boolean,
- isEnabled : Boolean = true,
+ clearAvailable: () -> Unit = {},
+ isAvailable: Boolean?,
) {
- var nickname by remember {
- mutableStateOf(initNickname ?: "")
- }
- var descriptionText by remember { mutableStateOf("닉네임 제한 캡션입니다") }
+ var nickname by remember {mutableStateOf(initNickname ?: "")}
+ val isEnabled by remember{derivedStateOf{ nickname != initNickname && nickname.isNotEmpty()}}
+ var descriptionText by remember {mutableStateOf("닉네임 제한 캡션입니다")}
var descriptionTextColor by remember { mutableStateOf(Color.Black) }
var nicknameLength by remember { mutableStateOf(nickname.length.toString()) }
@@ -37,6 +51,7 @@ fun NicknameInput(
descriptionText = handleText(isAvailable)
descriptionTextColor = handleTextColor(isAvailable)
}
+ LaunchedEffect(nickname){ if(initNickname != nickname) clearAvailable() }
Column(
horizontalAlignment = Alignment.Start,
@@ -45,7 +60,7 @@ fun NicknameInput(
) {
Column(modifier = Modifier.padding(horizontal = 15.dp)) {
Row(horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.Bottom) {
- Column() {
+ Column {
Row(
modifier = Modifier.fillMaxWidth(0.75f),
verticalAlignment = Alignment.CenterVertically,
@@ -59,13 +74,12 @@ fun NicknameInput(
focusedIndicatorColor = Color.White,
),
minLines = 1,
- textStyle = TextStyle(color = Color.Black, fontSize = 14.sp, fontWeight = FontWeight.Light),
+ textStyle = TextStyle(color = Color.Black, fontSize = 14.sp, fontWeight = FontWeight.Light, fontFamily = CustomFont.regular),
value = nickname,
onValueChange = {
- if (isLenthUnder9(it)) {
+ if (isLengthUnder9(it)) {
nickname = it
nicknameLength = it.length.toString()
- onChangeValue(it)
}
},
placeholder = {
@@ -93,16 +107,22 @@ fun NicknameInput(
)
}
}
- Divider(modifier = Modifier.border(width = 1.dp, color = CustomColor.gray2).fillMaxWidth(0.75f))
+ HorizontalDivider(modifier = Modifier
+ .border(width = 1.dp, color = CustomColor.gray2)
+ .fillMaxWidth(0.75f))
}
Column(modifier = Modifier.padding(start = 8.dp), verticalArrangement = Arrangement.Center) {
Button(
isEnabled,
"중복확인",
- { onPressNicknameExist(nickname) },
+ {
+ onPressNicknameExist(nickname)
+ },
textSize = 14,
radious = 10,
- buttonModifier = Modifier.height(46.dp).fillMaxWidth(1f),
+ buttonModifier = Modifier
+ .height(46.dp)
+ .fillMaxWidth(1f),
)
}
}
@@ -118,28 +138,56 @@ fun NicknameInput(
}
}
-fun handleText(isAvailable: Boolean): String {
- if (isAvailable) {
- return "사용가능한 닉네임 입니다"
+fun handleText(isAvailable: Boolean?): String {
+ return if (isAvailable == null){
+ "닉네임 제한 캡션입니다"
+ } else {
+ if (isAvailable) {
+ "사용가능한 닉네임 입니다"
+ } else {
+ "사용할 수 없는 닉네임 입니다"
+ }
}
- return "닉네임 제한 캡션입니다"
}
-fun isLenthUnder9(text: String): Boolean {
+fun isLengthUnder9(text: String): Boolean {
if (text.length < 9) return true
return false
}
-fun handleTextColor(isAvailable: Boolean): Color {
- if (isAvailable) {
- return CustomColor.blue
+fun handleTextColor(isAvailable: Boolean?): Color {
+ return if(isAvailable == null){
+ Color.Black
+ } else {
+ if (isAvailable) {
+ CustomColor.blue
+ } else {
+ CustomColor.red
+ }
}
- return Color.Black
}
@Preview
@Composable
fun NicknameInputPreview() {
- NicknameInput(null,{}, {}, true)
+ var nickname by remember{mutableStateOf("호준")}
+ var baseNickname = "안드"
+ var isDup by remember{mutableStateOf(false)}
+ Log.d("TAG TEST", "isDup : ${isDup}")
+ Box(
+ modifier = Modifier
+ .fillMaxSize()
+ .background(color = Color.White),
+ contentAlignment = Alignment.Center
+ ){
+ NicknameInput(
+ initNickname = nickname,
+ onPressNicknameExist = {
+ isDup = it==baseNickname
+ if(isDup) {baseNickname = nickname}
+ },
+ isAvailable = !isDup
+ )
+ }
}
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/NoteImageItem.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/NoteImageItem.kt
index d48d76889..95879455b 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/NoteImageItem.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/NoteImageItem.kt
@@ -35,6 +35,7 @@ fun NoteImageView(
isSelected: Boolean
) {
val index = if (isRecommanded) "Best!" else index
+ val nonSelectText = if (isRecommanded) "Best!" else ""
val itemBorderColor = if (isSelected) CustomColor.black else Color.Transparent
Box(
contentAlignment = Alignment.Center,
@@ -68,6 +69,17 @@ fun NoteImageView(
}
}
}
+ else{
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Center,
+ ) {
+ Text(
+ "${nonSelectText}",
+ style = TextStyle(color = Color.Black, fontFamily = pretendard, fontWeight = FontWeight.Bold)
+ )
+ }
+ }
}
}
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/NoteListItem.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/NoteListItem.kt
new file mode 100644
index 000000000..665793c00
--- /dev/null
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/NoteListItem.kt
@@ -0,0 +1,113 @@
+package com.hmoa.core_designsystem.component
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.wrapContentWidth
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.hmoa.core_common.formatWon
+import com.hmoa.core_designsystem.theme.CustomColor
+import com.hmoa.core_designsystem.theme.CustomFont
+import com.hmoa.core_model.response.Note
+
+@Composable
+fun NoteListItem(
+ noteUrl: String,
+ productName: String,
+ notes: List,
+ noteCounts: Int,
+ totalPrice: Int
+){
+ val notes = notes.joinToString { it.noteName }
+ val price = totalPrice / noteCounts
+ Row(
+ modifier = Modifier.fillMaxWidth().height(60.dp),
+ verticalAlignment = Alignment.Bottom
+ ){
+ CircleImageView(
+ imgUrl = noteUrl,
+ width = 60,
+ height = 60
+ )
+ Spacer(Modifier.width(20.dp))
+ Column(
+ modifier = Modifier.weight(1f).fillMaxHeight(),
+ verticalArrangement = Arrangement.Center
+ ){
+ Text(
+ text = productName,
+ fontSize = 14.sp,
+ fontFamily = CustomFont.semiBold
+ )
+ Spacer(Modifier.height(4.dp))
+ Text(
+ text = notes,
+ fontSize = 10.sp,
+ fontFamily = CustomFont.regular
+ )
+ Spacer(Modifier.height(6.dp))
+ Text(
+ text = "수량 ${noteCounts}개",
+ fontSize = 10.sp,
+ fontFamily = CustomFont.regular,
+ color = CustomColor.gray3
+ )
+ }
+ Spacer(Modifier.width(10.dp))
+ Column(
+ modifier = Modifier.wrapContentWidth(),
+ verticalArrangement = Arrangement.Bottom,
+ horizontalAlignment = Alignment.End
+ ) {
+ Text(
+ text = "${formatWon(price)}원/개",
+ fontSize = 10.sp,
+ fontFamily = CustomFont.regular,
+ color = CustomColor.gray3,
+ )
+ Spacer(Modifier.height(3.dp))
+ Text(
+ text = "${formatWon(totalPrice)}원",
+ fontSize = 14.sp,
+ fontFamily = CustomFont.semiBold
+ )
+ }
+ }
+}
+
+@Preview
+@Composable
+private fun NoteListItemUITest(){
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .background(color = Color.White)
+ ){
+ NoteListItem(
+ noteUrl = "https://hmoa-note.s3.ap-northeast-2.amazonaws.com/%EC%8B%9C%ED%8A%B8%EB%9F%AC%EC%8A%A4/note-1/110d8e9b-994d-42ff-96be-7e7bab50c073.jpeg",
+ productName = "시트러스",
+ notes = listOf(
+ Note(noteName = "라임 만다린", noteContent = ""),
+ Note(noteName = "베르가뭇", noteContent = ""),
+ Note(noteName = "비터오렌지", noteContent = ""),
+ Note(noteName = "자몽", noteContent = ""),
+ ),
+ noteCounts = 4,
+ totalPrice = 4800
+ )
+ }
+}
\ No newline at end of file
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/NoteSelectedDescription.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/NoteSelectedDescription.kt
new file mode 100644
index 000000000..26ef5c915
--- /dev/null
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/NoteSelectedDescription.kt
@@ -0,0 +1,130 @@
+package com.hmoa.core_designsystem.component
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.wrapContentHeight
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.hmoa.core_designsystem.theme.CustomColor
+import com.hmoa.core_designsystem.theme.CustomFont
+import com.hmoa.core_model.response.Note
+
+@Composable
+fun NoteSelectedDescription(
+ imgUrl: String,
+ imgSize: Int,
+ productName: String,
+ price: Int,
+ categoryNumber: Int,
+ notes: List,
+){
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .wrapContentHeight()
+ .background(color = CustomColor.gray1, shape = RoundedCornerShape(size = 5.dp))
+ .padding(start = 16.dp, end = 12.dp, top = 20.dp, bottom = 16.dp)
+ ){
+ CircleImageView(
+ imgUrl = imgUrl,
+ width = imgSize,
+ height = imgSize
+ )
+ Spacer(Modifier.width(19.dp))
+ Column(
+ modifier = Modifier.weight(1f)
+ ){
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically
+ ){
+ Text(
+ text = productName,
+ fontSize = 14.sp,
+ fontFamily = CustomFont.bold
+ )
+ Text(
+ text = "${price}원",
+ fontSize = 14.sp,
+ fontFamily = CustomFont.regular
+ )
+ }
+ Text(
+ text = "(${categoryNumber}가지 향료)",
+ fontSize = 12.sp,
+ fontFamily = CustomFont.regular
+ )
+ Spacer(Modifier.height(8.dp))
+ notes.forEach{ note ->
+ Row(
+ verticalAlignment = Alignment.CenterVertically
+ ){
+ Text(
+ text = "· ",
+ fontSize = 16.sp,
+ fontFamily = CustomFont.extraBold
+ )
+ Text(
+ text = "${note.noteName} : ${note.noteContent}",
+ fontSize = 12.sp,
+ fontFamily = CustomFont.regular
+ )
+ }
+ if (notes.indexOf(note) != notes.lastIndex){
+ Spacer(Modifier.height(3.dp))
+ }
+ }
+ }
+ }
+}
+
+@Preview
+@Composable
+private fun TestUI(){
+ val sample = listOf(
+ Note(
+ noteName = "통카빈",
+ noteContent = "열대 나무 씨앗을 말린 향신료"
+ ),
+ Note(
+ noteName = "넛맥",
+ noteContent = "넛맥이란 식물을 말린 향신료"
+ ),
+ Note(
+ noteName = "페퍼",
+ noteContent = "후추"
+ )
+ )
+ Box(
+ modifier = Modifier.fillMaxSize()
+ .background(color = Color.White)
+ .padding(horizontal = 12.dp),
+ contentAlignment = Alignment.Center
+ ){
+ NoteSelectedDescription(
+ imgUrl = "",
+ imgSize = 66,
+ productName = "프루트",
+ price = 4800,
+ categoryNumber = 3,
+ notes = sample
+ )
+ }
+}
\ No newline at end of file
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/OrderHistoryItem.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/OrderHistoryItem.kt
new file mode 100644
index 000000000..bf74e515c
--- /dev/null
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/OrderHistoryItem.kt
@@ -0,0 +1,376 @@
+package com.hmoa.core_designsystem.component
+
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.wrapContentWidth
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.HorizontalDivider
+import androidx.compose.material3.OutlinedButton
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.text.PlatformTextStyle
+import androidx.compose.ui.text.TextStyle
+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.hmoa.core_common.formatWon
+import com.hmoa.core_common.toDisplayString
+import com.hmoa.core_designsystem.theme.CustomColor
+import com.hmoa.core_designsystem.theme.CustomFont
+import com.hmoa.core_model.data.OrderStatus
+import com.hmoa.core_model.response.Note
+import com.hmoa.core_model.response.NoteProduct
+
+@Composable
+fun OrderRecordItem(
+ courierCompany: String?,
+ shippingType: OrderStatus,
+ products: List,
+ totalPrice: Int,
+ shippingPayment: Int,
+ trackingNumber: String?,
+ createdAt: String,
+ isReviewed: Boolean,
+ onRefundClick: () -> Unit,
+ onReturnClick: () -> Unit,
+ onReviewWriteClick: () -> Unit,
+){
+ val shippingStatus = shippingType.toDisplayString()
+ val shippingStatusColor = if(shippingType == OrderStatus.SHIPPING_COMPLETE) CustomColor.blue else Color.Black
+ val buttonText = if(shippingType == OrderStatus.SHIPPING_PROGRESS || shippingType == OrderStatus.SHIPPING_COMPLETE) "반품 신청" else "환불 신청"
+ val buttonEvent = if(shippingType == OrderStatus.PURCHASE_CONFIRMATION) onReturnClick else onRefundClick
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(bottom = 24.dp)
+ ){
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ verticalAlignment = Alignment.CenterVertically
+ ){
+ Text(
+ text = shippingStatus,
+ fontSize = 12.sp,
+ fontFamily = CustomFont.bold,
+ color = shippingStatusColor
+ )
+ Spacer(Modifier.width(12.dp))
+ HorizontalDivider(modifier = Modifier.weight(1f), thickness = 1.dp, color = Color.Black)
+ Spacer(Modifier.width(12.dp))
+ Text(
+ modifier = Modifier.wrapContentWidth(),
+ text = createdAt,
+ fontSize = 12.sp,
+ fontFamily = CustomFont.bold,
+ color = Color.Black
+ )
+ }
+ Spacer(Modifier.height(20.dp))
+ products.forEach{
+ ProductView(it)
+ Spacer(Modifier.height(30.dp))
+ }
+ if (courierCompany != null && trackingNumber != null){
+ Text(
+ modifier = Modifier.padding(start = 80.dp),
+ text = "택배사 : ${courierCompany}\n운송장 번호 : ${trackingNumber}",
+ textAlign = TextAlign.Justify,
+ style = TextStyle(
+ fontSize = 10.sp,
+ color = CustomColor.gray3,
+ fontFamily = CustomFont.regular,
+ platformStyle = PlatformTextStyle(includeFontPadding = false)
+ )
+ )
+ Spacer(Modifier.height(24.dp))
+ }
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalArrangement = Arrangement.End
+ ){
+ Text(
+ text = "배송비",
+ fontSize = 12.sp,
+ fontFamily = CustomFont.medium,
+ color = CustomColor.gray3
+ )
+ Spacer(Modifier.width(7.dp))
+ Text(
+ text = "${formatWon(shippingPayment)}원",
+ fontSize = 12.sp,
+ fontFamily = CustomFont.medium,
+ color = CustomColor.gray3
+ )
+ }
+ Spacer(Modifier.height(24.dp))
+ HorizontalDivider(color = CustomColor.gray1, thickness = 1.dp, modifier = Modifier.fillMaxWidth())
+ Spacer(Modifier.height(24.dp))
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalArrangement = Arrangement.SpaceBetween
+ ){
+ Text(
+ text = "결제금액",
+ fontSize = 18.sp,
+ fontFamily = CustomFont.bold,
+ )
+ Text(
+ text = "${formatWon(totalPrice)}원",
+ fontSize = 18.sp,
+ fontFamily = CustomFont.bold,
+ color = CustomColor.red
+ )
+ }
+ Spacer(Modifier.height(32.dp))
+ Buttons(
+ isReviewed = isReviewed,
+ shippingStatus = shippingType,
+ buttonText = buttonText,
+ buttonEvent = buttonEvent,
+ onReviewWriteClick = onReviewWriteClick
+ )
+
+ }
+}
+
+@Composable
+fun ProductView(
+ product: NoteProduct
+){
+ val notes = product.notes.joinToString {it.noteName}
+ val price = product.price / product.notesCount
+
+ Row(modifier = Modifier.fillMaxWidth()){
+ CircleImageView(
+ imgUrl = product.productPhotoUrl,
+ width = 60,
+ height = 60
+ )
+ Spacer(Modifier.width(20.dp))
+ Column(modifier = Modifier.fillMaxWidth()){
+ Text(
+ text = product.productName,
+ fontSize = 14.sp,
+ fontFamily = CustomFont.semiBold
+ )
+ Spacer(Modifier.height(4.dp))
+ Text(
+ text = notes,
+ fontSize = 10.sp,
+ fontFamily = CustomFont.medium
+ )
+ Spacer(Modifier.height(6.dp))
+ Text(
+ text = "수량 ${product.notesCount}개 ${formatWon(price)}원/개",
+ fontSize = 10.sp,
+ fontFamily = CustomFont.medium,
+ color = CustomColor.gray3
+ )
+ Spacer(Modifier.height(12.dp))
+ Text(
+ text = "${formatWon(product.price)}원",
+ fontSize = 14.sp,
+ fontFamily = CustomFont.semiBold,
+ )
+ }
+ }
+}
+
+@Composable
+private fun Buttons(
+ isReviewed: Boolean,
+ shippingStatus: OrderStatus,
+ buttonText: String,
+ buttonEvent: () -> Unit,
+ onReviewWriteClick: () -> Unit,
+){
+ val twoButtonStatusList = listOf(
+ OrderStatus.SHIPPING_PROGRESS,
+ OrderStatus.SHIPPING_COMPLETE,
+ OrderStatus.RETURN_COMPLETE,
+ OrderStatus.RETURN_PROGRESS
+ )
+ if (shippingStatus in twoButtonStatusList){
+ Row(
+ modifier = Modifier.fillMaxWidth()
+ ){
+ val buttonEnabled = shippingStatus == OrderStatus.SHIPPING_PROGRESS
+ || shippingStatus == OrderStatus.SHIPPING_COMPLETE
+ OutlinedButton(
+ modifier = Modifier.weight(1f),
+ shape = RoundedCornerShape(3.dp),
+ onClick = buttonEvent,
+ enabled = buttonEnabled,
+ border = BorderStroke(width = 1.dp, color = if(buttonEnabled) Color.Black else CustomColor.gray3),
+ contentPadding = PaddingValues(vertical = 10.dp),
+ ) {
+ Text(
+ text = buttonText,
+ fontSize = 12.sp,
+ color = if(buttonEnabled) Color.Black else CustomColor.gray3,
+ fontFamily = CustomFont.semiBold
+ )
+ }
+ Spacer(Modifier.width(20.dp))
+ Column(
+ modifier = Modifier.weight(1f)
+ ){
+ OutlinedButton(
+ modifier = Modifier.fillMaxWidth(),
+ shape = RoundedCornerShape(3.dp),
+ onClick = onReviewWriteClick,
+ enabled = shippingStatus != OrderStatus.SHIPPING_PROGRESS && (!isReviewed),
+ border = BorderStroke(width = 1.dp, color = if(!isReviewed) Color.Black else CustomColor.gray3),
+ contentPadding = PaddingValues(vertical = 10.dp),
+ ) {
+ Text(
+ text = "후기 작성(이벤트 자동 응모)",
+ fontSize = 12.sp,
+ color = if(!isReviewed) Color.Black else CustomColor.gray3,
+ fontFamily = CustomFont.semiBold
+ )
+ }
+ Text(
+ modifier = Modifier.fillMaxWidth().padding(horizontal = 10.dp),
+ text = "(5만원 상당 향수 증정 이벤트 응모)\n자세한 내용은 향모아 인스타그램에서 확인하세요.",
+ fontSize = 10.sp,
+ lineHeight = 12.sp,
+ fontFamily = CustomFont.regular,
+ color = Color.Black,
+ textAlign = TextAlign.Center
+ )
+ }
+ }
+ } else {
+ val buttonEnabled = shippingStatus == OrderStatus.PAY_COMPLETE
+ OutlinedButton(
+ modifier = Modifier.fillMaxWidth(),
+ shape = RoundedCornerShape(3.dp),
+ onClick = buttonEvent,
+ enabled = buttonEnabled,
+ border = BorderStroke(width = 1.dp, color = if(buttonEnabled) Color.Black else CustomColor.gray3),
+ contentPadding = PaddingValues(vertical = 10.dp),
+ ) {
+ Text(
+ text = buttonText,
+ fontSize = 12.sp,
+ color = if(buttonEnabled) Color.Black else CustomColor.gray3,
+ fontFamily = CustomFont.semiBold
+ )
+ }
+ }
+}
+
+@Preview
+@Composable
+private fun OrderHistoryItemUiTest(){
+ val scrollState = rememberScrollState()
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .background(color = Color.White)
+ .padding(horizontal = 16.dp)
+ .verticalScroll(state = scrollState)
+ ){
+ OrderRecordItem(
+ courierCompany = "대한통운(CJ)",
+ trackingNumber = "365861396573",
+ shippingType = OrderStatus.PAY_FAILED,
+ products = listOf(
+ NoteProduct(
+ notes = listOf(
+ Note(noteName = "라임 만다란", noteContent = ""),
+ Note(noteName = "베르가못", noteContent = ""),
+ Note(noteName = "비터 오렌지", noteContent = ""),
+ Note(noteName = "자몽", noteContent = "")
+ ),
+ notesCount = 4,
+ price = 4800,
+ productId = 0,
+ productName = "시트러스",
+ productPhotoUrl = ""
+ ),
+ NoteProduct(
+ notes = listOf(
+ Note(noteName = "네롤리", noteContent = ""),
+ Note(noteName = "화이트 로즈", noteContent = ""),
+ Note(noteName = "핑크 로즈", noteContent = ""),
+ Note(noteName = "화이트 로즈", noteContent = ""),
+ Note(noteName = "바이올렛", noteContent = ""),
+ Note(noteName = "피오니", noteContent = "")
+ ),
+ notesCount = 6,
+ price = 7200,
+ productId = 0,
+ productName = "플로럴",
+ productPhotoUrl = ""
+ )
+ ),
+ totalPrice = 15000,
+ onRefundClick = {},
+ onReturnClick = {},
+ shippingPayment = 3000,
+ onReviewWriteClick = {},
+ createdAt = "2024/10/17",
+ isReviewed = true
+ )
+ OrderRecordItem(
+ courierCompany = "대한통운(CJ)",
+ trackingNumber = "365861396573",
+ shippingType = OrderStatus.PAY_COMPLETE,
+ products = listOf(
+ NoteProduct(
+ notes = listOf(
+ Note(noteName = "라임 만다란", noteContent = ""),
+ Note(noteName = "베르가못", noteContent = ""),
+ Note(noteName = "비터 오렌지", noteContent = ""),
+ Note(noteName = "자몽", noteContent = "")
+ ),
+ notesCount = 4,
+ price = 1200,
+ productId = 0,
+ productName = "시트러스",
+ productPhotoUrl = ""
+ ),
+ NoteProduct(
+ notes = listOf(
+ Note(noteName = "네롤리", noteContent = ""),
+ Note(noteName = "화이트 로즈", noteContent = ""),
+ Note(noteName = "핑크 로즈", noteContent = ""),
+ Note(noteName = "화이트 로즈", noteContent = ""),
+ Note(noteName = "바이올렛", noteContent = ""),
+ Note(noteName = "피오니", noteContent = "")
+ ),
+ notesCount = 6,
+ price = 1200,
+ productId = 0,
+ productName = "플로럴",
+ productPhotoUrl = ""
+ )
+ ),
+ totalPrice = 15000,
+ onRefundClick = {},
+ onReturnClick = {},
+ shippingPayment = 3000,
+ onReviewWriteClick = {},
+ createdAt = "2024/07/21",
+ isReviewed = false
+ )
+ }
+}
\ No newline at end of file
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/PerfumeItemView.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/PerfumeItemView.kt
index 7ab4c3bf1..f57c261cf 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/PerfumeItemView.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/PerfumeItemView.kt
@@ -13,7 +13,7 @@ import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
-import com.hmoa.core_designsystem.theme.pretendard
+import com.hmoa.core_designsystem.theme.CustomFont
@Composable
fun PerfumeItemView(
@@ -29,8 +29,9 @@ fun PerfumeItemView(
) {
Column(modifier = Modifier.width(containerWidth.dp)) {
Column(
- modifier = Modifier.width(containerWidth.dp).height(containerHeight.dp)
- .background(imageBackgroundColor).border(border = imageBorderStroke?: BorderStroke(width = 0.dp, color = Color.Transparent)),
+ modifier = Modifier.width(containerWidth.dp).height(containerHeight.dp).padding(end = 8.dp)
+ .background(imageBackgroundColor)
+ .border(border = imageBorderStroke ?: BorderStroke(width = 0.dp, color = Color.Transparent)),
horizontalAlignment = androidx.compose.ui.Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
@@ -43,14 +44,17 @@ fun PerfumeItemView(
)
}
Text(
- text = brandName, style = TextStyle(fontSize = 14.sp, fontWeight = FontWeight.Normal,
- fontFamily = pretendard
+ text = brandName, style = TextStyle(
+ fontSize = 14.sp, fontWeight = FontWeight.Normal,
+ fontFamily = CustomFont.regular
),
modifier = Modifier.padding(end = 4.dp, top = 8.dp, bottom = 6.dp)
)
Text(
- text = perfumeName, style = TextStyle(fontSize = 12.sp,fontWeight = FontWeight.Normal,
- fontFamily = pretendard),
+ text = perfumeName, style = TextStyle(
+ fontSize = 12.sp, fontWeight = FontWeight.Normal,
+ fontFamily = CustomFont.regular
+ ),
modifier = Modifier.padding(end = 4.dp), softWrap = true
)
}
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/PerfumeWithCountItemView.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/PerfumeWithCountItemView.kt
index 17f1b64b9..45293936b 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/PerfumeWithCountItemView.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/PerfumeWithCountItemView.kt
@@ -4,7 +4,12 @@ import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
@@ -21,7 +26,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.hmoa.core_designsystem.R
import com.hmoa.core_designsystem.theme.CustomColor
-import com.hmoa.core_designsystem.theme.pretendard
+import com.hmoa.core_designsystem.theme.CustomFont
@Composable
fun PerfumeWithCountItemView(
@@ -64,7 +69,7 @@ fun PerfumeWithCountItemView(
) {
Text(
text = brandName, style = TextStyle(fontSize = 14.sp, fontWeight = FontWeight.Normal,
- fontFamily = pretendard),
+ fontFamily = CustomFont.regular),
)
TypeBadge(
roundedCorner = 20.dp,
@@ -83,7 +88,7 @@ fun PerfumeWithCountItemView(
text = perfumeName,
style = TextStyle(
fontSize = 12.sp, fontWeight = FontWeight.Normal,
- fontFamily = pretendard, textAlign = TextAlign.Start
+ fontFamily = CustomFont.regular, textAlign = TextAlign.Start
),
modifier = Modifier.width(containerWidth.dp).padding(end = 4.dp).padding(bottom = 2.dp),
softWrap = true
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/PostContent.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/PostContent.kt
index 3df8d584b..7f7e8d743 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/PostContent.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/PostContent.kt
@@ -4,7 +4,18 @@ import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTapGestures
-import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.requiredWidth
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.CircleShape
@@ -13,7 +24,11 @@ import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
-import androidx.compose.runtime.*
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@@ -44,9 +59,9 @@ fun PostContent(
dateDiff: String,
title: String,
content: String,
- heartCount: String,
+ heartCount: Int,
isLiked: Boolean,
- onChangeLike: () -> Unit,
+ onChangeLike: (isLiked: Boolean) -> Unit,
pictures: List
) {
//pager state
@@ -59,6 +74,9 @@ fun PostContent(
val screenWidth = configuration.screenWidthDp.toFloat()
val screenHeight = configuration.screenHeightDp.toFloat()
+ var isLiked by remember{mutableStateOf(isLiked)}
+ var heartCount by remember{mutableStateOf(heartCount)}
+
val nicknameTextStyle = TextStyle(
fontSize = 14.sp,
color = Color.Black,
@@ -133,8 +151,50 @@ fun PostContent(
Text(text = title, style = titleTextStyle)
}
+ Spacer(Modifier.height(15.dp))
+
+ Text(text = content,style = contentTextStyle)
+
+ if(pictures.isNotEmpty()){
+ Spacer(Modifier.height(17.dp))
+
+ HorizontalPager(
+ modifier = Modifier
+ .width(274.dp)
+ .height(304.dp)
+ .align(Alignment.CenterHorizontally),
+ state = state
+ ) {
+ Column(modifier = Modifier.fillMaxSize()){
+ ExpandableImage(
+ modifier = Modifier.requiredWidth(width),
+ picture = pictures[it],
+ width = screenWidth,
+ height = screenHeight
+ )
+ }
+ }
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(30.dp),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.spacedBy(8.dp, alignment = Alignment.CenterHorizontally)
+ ){
+ for(i in pictures.indices){
+ Box(
+ modifier = Modifier
+ .size(8.dp)
+ .background(color = if (i == state.currentPage) Color.Black else CustomColor.blackTrans30, shape = CircleShape)
+ .clip(CircleShape)
+ )
+ }
+ }
+ }
+
Spacer(Modifier.height(17.dp))
+
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.End,
@@ -142,7 +202,9 @@ fun PostContent(
) {
IconButton(
onClick = {
- onChangeLike()
+ if(isLiked) heartCount-- else heartCount++
+ onChangeLike(isLiked)
+ isLiked = !isLiked
}
) {
Icon(
@@ -153,7 +215,7 @@ fun PostContent(
)
}
- Text(text = heartCount, style = viewNumberTextStyle)
+ Text(text = if (heartCount > 999) "999+" else heartCount.toString(), style = viewNumberTextStyle)
}
Spacer(Modifier.height(14.dp))
@@ -174,7 +236,8 @@ private fun ExpandableImage(
onDismissRequest = { showDialog = false }
) {
Box(
- modifier = modifier.width(width.dp)
+ modifier = modifier
+ .width(width.dp)
.height(height.dp),
contentAlignment = Alignment.Center
) {
@@ -186,7 +249,8 @@ private fun ExpandableImage(
contentScale = ContentScale.FillWidth
)
Row(
- modifier = Modifier.fillMaxSize()
+ modifier = Modifier
+ .fillMaxSize()
.padding(start = 16.dp, top = 19.dp),
verticalAlignment = Alignment.Top,
horizontalArrangement = Arrangement.Start
@@ -239,7 +303,7 @@ fun PostContentPreview() {
dateDiff = "76",
title = "안녕하셈",
content = "반갑습니다 ㅎㅎ",
- heartCount = "3",
+ heartCount = 3,
isLiked = false,
onChangeLike = {},
pictures = emptyList()
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/PostListItem.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/PostListItem.kt
index 20dd4bbda..91eda342c 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/PostListItem.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/PostListItem.kt
@@ -32,6 +32,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.hmoa.core_designsystem.R
import com.hmoa.core_designsystem.theme.CustomColor
+import com.hmoa.core_designsystem.theme.CustomFont
import com.hmoa.core_designsystem.theme.pretendard
@Composable
@@ -45,6 +46,7 @@ fun PostListItem(
){
Row(
modifier = modifier
+ .background(color = Color.White)
.clickable {
onPostClick()
}
@@ -77,7 +79,6 @@ fun PostListItem(
icon = R.drawable.ic_heart_filled,
count = heartCount
)
- Spacer(Modifier.width(8.dp))
}
if (commentCount > 0) {
Spacer(Modifier.width(8.dp))
@@ -95,10 +96,46 @@ fun PostListItem(
fontSize = 16.sp,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
+ fontFamily = CustomFont.regular,
+ color = Color.Black
)
}
}
}
+
+@Preview(showBackground = true)
+@Composable
+fun TestPostListItem(){
+ Column(
+ modifier = Modifier.fillMaxSize()
+ ){
+ PostListItem (
+ Modifier
+ .fillMaxWidth()
+ .height(52.dp)
+ .border(width = 1.dp, color = CustomColor.gray2, shape = RoundedCornerShape(10.dp)),
+ onPostClick = {},
+ postType = "추천해주세요",
+ postTitle = "여자친구한테 선물할 향수 뭐가 좋을까요?",
+ heartCount = 10,
+ commentCount = 10
+ )
+ Spacer(Modifier.height(10.dp))
+ PostListItem (
+ Modifier
+ .fillMaxWidth()
+ .height(52.dp)
+ .border(width = 1.dp, color = CustomColor.gray2, shape = RoundedCornerShape(10.dp)),
+ onPostClick = {},
+ postType = "추천해주세요",
+ postTitle = "여자친구한테 선물할 향수 뭐가 좋을까요?",
+ heartCount = 10,
+ commentCount = 0
+ )
+
+ }
+}
+
@Composable
fun CountBadge(
icon : Int,
@@ -127,46 +164,4 @@ fun CountBadge(
color = Color.Black,
)
}
-}
-
-@Preview(showBackground = true)
-@Composable
-fun TestPostListItem(){
- Column(
- modifier = Modifier.fillMaxSize()
- ){
- Column(
- modifier = Modifier.fillMaxWidth()
- .height(200.dp)
- ){
- PostListItem (
- Modifier
- .fillMaxWidth()
- .wrapContentHeight()
- .border(width = 1.dp, color = CustomColor.gray2, shape = RoundedCornerShape(10.dp)),
- onPostClick = {},
- postType = "추천해주세요",
- postTitle = "여자친구한테 선물할 향수 뭐가 좋을까요?",
- heartCount = 10,
- commentCount = 10
- )
- }
- Spacer(Modifier.height(10.dp))
- Column(
- modifier = Modifier.fillMaxWidth()
- .height(200.dp)
- ){
- PostListItem (
- Modifier
- .fillMaxWidth()
- .wrapContentHeight()
- .border(width = 1.dp, color = CustomColor.gray2, shape = RoundedCornerShape(10.dp)),
- onPostClick = {},
- postType = "추천해주세요",
- postTitle = "여자친구한테 선물할 향수 뭐가 좋을까요?",
- heartCount = 0,
- commentCount = 10
- )
- }
- }
-}
+}
\ No newline at end of file
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/ProgressBar.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/ProgressBar.kt
index c157c6251..e77a1d533 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/ProgressBar.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/ProgressBar.kt
@@ -18,9 +18,10 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
/** Iterate the progress value */
-suspend fun loadProgress(updateProgress: (Float) -> Unit) {
+suspend fun loadProgress(stepSize: Float, updateProgress: (Float) -> Unit) {
+
for (i in 1..100) {
- updateProgress(1f / 100)
+ updateProgress(stepSize)
delay(5)
}
}
@@ -52,7 +53,7 @@ fun ProgressBarPreview() {
androidx.compose.material3.Button(onClick = {
targetProgress += additionalProgress
scope.launch {
- loadProgress { progress ->
+ loadProgress(additionalProgress) { progress ->
if (currentProgress <= targetProgress) {
currentProgress += progress
}
@@ -67,7 +68,7 @@ fun ProgressBarPreview() {
androidx.compose.material3.Button(onClick = {
targetProgress -= additionalProgress
scope.launch {
- loadProgress { progress ->
+ loadProgress(additionalProgress) { progress ->
if (currentProgress >= targetProgress) {
currentProgress -= progress
}
@@ -77,4 +78,4 @@ fun ProgressBarPreview() {
Text("substract")
}
}
-}
\ No newline at end of file
+}
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/ReviewItem.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/ReviewItem.kt
new file mode 100644
index 000000000..c0e8ed2b1
--- /dev/null
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/ReviewItem.kt
@@ -0,0 +1,285 @@
+package com.hmoa.core_designsystem.component
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.gestures.detectTapGestures
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.wrapContentHeight
+import androidx.compose.foundation.lazy.LazyRow
+import androidx.compose.foundation.lazy.items
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.Close
+import androidx.compose.material3.BasicAlertDialog
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.LocalConfiguration
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.compose.ui.window.DialogProperties
+import com.hmoa.core_designsystem.R
+import com.hmoa.core_designsystem.theme.CustomColor
+import com.hmoa.core_designsystem.theme.CustomFont
+import kotlinx.coroutines.delay
+
+@Composable
+fun ReviewItem(
+ isItemClickable: Boolean,
+ reviewId: Int,
+ profileImg: String,
+ nickname: String,
+ writtenAt: String,
+ isLiked: Boolean,
+ heartNumber: Int,
+ content: String,
+ images: List,
+ category: String,
+ onHeartClick: (reviewId: Int, isLiked: Boolean) -> Unit,
+ onMenuClick: () -> Unit,
+ onItemClick: () -> Unit,
+){
+ var isLiked by remember{mutableStateOf(isLiked)}
+ var heartNumber by remember{mutableStateOf(heartNumber)}
+ var isDelayed by remember{mutableStateOf(true)}
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .wrapContentHeight()
+ .background(color = CustomColor.gray5, shape = RoundedCornerShape(size = 5.dp))
+ .clickable { if (isItemClickable) onItemClick() }
+ .padding(top = 12.dp, start = 16.dp, end = 16.dp, bottom = 10.dp),
+ ){
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ verticalAlignment = Alignment.CenterVertically
+ ){
+ CircleImageView(
+ imgUrl = profileImg,
+ width = 28,
+ height = 28
+ )
+ Spacer(Modifier.width(6.dp))
+ Text(
+ text = nickname,
+ fontSize = 14.sp,
+ color = CustomColor.gray1,
+ fontFamily = CustomFont.regular
+ )
+ Spacer(Modifier.width(8.dp))
+ Text(
+ text = writtenAt,
+ fontSize = 10.sp,
+ color = CustomColor.gray3,
+ fontFamily = CustomFont.medium
+ )
+ Spacer(Modifier.weight(1f))
+ IconButton(
+ modifier = Modifier.size(16.dp),
+ onClick = {
+ if (isLiked) heartNumber-- else heartNumber++
+ onHeartClick(reviewId, isLiked)
+ isLiked = !isLiked
+ isDelayed = false
+ },
+ enabled = isDelayed
+ ) {
+ Image(
+ modifier = Modifier.fillMaxSize(),
+ painter = painterResource(if(isLiked) R.drawable.ic_heart_selectable_selected else R.drawable.ic_heart_selectable_not_selected),
+ contentDescription = "Heart Icon"
+ )
+ }
+ Spacer(Modifier.width(5.dp))
+ Text(
+ text = heartNumber.toString(),
+ fontSize = 14.sp,
+ fontFamily = CustomFont.regular
+ )
+ Spacer(Modifier.width(10.dp))
+ IconButton(
+ modifier = Modifier.width(10.dp),
+ onClick = onMenuClick
+ ){
+ Icon(
+ painter = painterResource(R.drawable.ic_vertical_three_dot_menu),
+ tint = CustomColor.gray2,
+ contentDescription = "Menu Button"
+ )
+ }
+ }
+ Spacer(Modifier.height(12.dp))
+ Text(
+ modifier = Modifier.fillMaxWidth(),
+ text = content,
+ fontSize = 12.sp,
+ fontFamily = CustomFont.regular,
+ color = Color.White,
+ maxLines = 3,
+ overflow = TextOverflow.Ellipsis,
+ lineHeight = 17.sp,
+ )
+ Spacer(Modifier.height(20.dp))
+ if (images.isNotEmpty()){Images(images = images)}
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalArrangement = Arrangement.End
+ ){
+ Text(
+ text = "향BTI 시향카드 [${category}]",
+ fontSize = 12.sp,
+ fontFamily = CustomFont.regular,
+ color = Color.White
+ )
+ }
+ }
+ LaunchedEffect(isDelayed){
+ if(!isDelayed){
+ delay(200)
+ isDelayed = true
+ }
+ }
+}
+
+@Composable
+private fun Images(images: List){
+ LazyRow(
+ modifier = Modifier.padding(bottom = 20.dp),
+ horizontalArrangement = Arrangement.spacedBy(12.dp)
+ ){
+ items(images){ image -> ExpandableImage(picture = image)}
+ }
+}
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+private fun ExpandableImage(
+ picture : String
+){
+ var showDialog by remember{mutableStateOf(false)}
+ val configuration = LocalConfiguration.current
+
+ if (showDialog) {
+ BasicAlertDialog(
+ modifier = Modifier
+ .height(configuration.screenHeightDp.dp)
+ .width(configuration.screenWidthDp.dp),
+ onDismissRequest = { showDialog = false },
+ properties = DialogProperties(usePlatformDefaultWidth = false)
+ ) {
+ Box(
+ modifier = Modifier.fillMaxSize(),
+ contentAlignment = Alignment.Center
+ ){
+ ImageView(
+ imageUrl = picture,
+ width = 1f,
+ height = 1f,
+ backgroundColor = Color.Black,
+ contentScale = ContentScale.FillWidth
+ )
+ Row(
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(start = 16.dp, top = 19.dp),
+ verticalAlignment = Alignment.Top,
+ horizontalArrangement = Arrangement.Start
+ ){
+ IconButton(
+ modifier = Modifier.size(24.dp),
+ onClick = {showDialog = false}
+ ){
+ Icon(
+ imageVector = Icons.Filled.Close,
+ contentDescription = "Close Dialog",
+ tint = Color.White
+ )
+ }
+ }
+ }
+ }
+ }
+
+ Box(
+ modifier = Modifier
+ .size(80.dp)
+ .background(color = CustomColor.gray1)
+ .pointerInput(Unit) {
+ detectTapGestures {
+ showDialog = !showDialog
+ }
+ },
+ contentAlignment = Alignment.Center
+ ){
+ //image view
+ ImageView(
+ imageUrl = picture,
+ width = 1f,
+ height = 1f,
+ backgroundColor = CustomColor.gray1,
+ contentScale = ContentScale.FillWidth
+ )
+ }
+}
+
+@Composable
+@Preview
+private fun ReviewItemUITest(){
+ var isLiked by remember{mutableStateOf(false)}
+ var text by remember{mutableStateOf("")}
+ var curN by remember{mutableStateOf(0)}
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .background(color = Color.White)
+ ){
+ ReviewItem(
+ isItemClickable = false,
+ reviewId = 0,
+ profileImg = "",
+ nickname = "향수 러버",
+ writtenAt = "10일 전",
+ isLiked = isLiked,
+ heartNumber = 12,
+ content = "평소에 선호하는 향이 있었는데 그 향의 이름을 몰랐는데 향료 배송받고 시향해보니 통카 빈?이더라구요 제가 좋아했던 향수들은 다 통카 빈이 들어가있네요 ㅎ 저같은 분들한테 추천합니다",
+ images = listOf("","","","",""),
+ category = "시트러스",
+ onHeartClick = {a,b -> },
+ onMenuClick = {},
+ onItemClick = {
+ curN += 1
+ text = "item click : ${curN}"
+ }
+ )
+ Text(
+ text = text,
+ fontSize = 30.sp
+ )
+ }
+}
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/SearchTopBar.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/SearchTopBar.kt
index dd052a3d9..8c6613536 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/SearchTopBar.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/SearchTopBar.kt
@@ -2,30 +2,14 @@ package com.hmoa.core_designsystem.component
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
-import androidx.compose.material3.ExperimentalMaterial3Api
-import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
-import androidx.compose.material3.Text
-import androidx.compose.material3.TopAppBar
-import androidx.compose.material3.TopAppBarColors
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
+import androidx.compose.material3.*
+import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@@ -39,8 +23,11 @@ import androidx.compose.ui.unit.sp
import com.hmoa.core_designsystem.R
import com.hmoa.core_designsystem.theme.CustomColor
import com.hmoa.core_designsystem.theme.pretendard
+import kotlinx.coroutines.FlowPreview
+import kotlinx.coroutines.flow.debounce
+import kotlinx.coroutines.flow.filter
-@OptIn(ExperimentalMaterial3Api::class)
+@OptIn(ExperimentalMaterial3Api::class, FlowPreview::class)
@Composable
fun SearchTopBar(
searchWord: String,
@@ -49,6 +36,12 @@ fun SearchTopBar(
onClickSearch: () -> Unit,
navBack: () -> Unit,
) {
+ var searchWord by remember { mutableStateOf("") }
+ val textFlow = remember { snapshotFlow { searchWord } }
+
+ LaunchedEffect(textFlow) {
+ textFlow.debounce(700).filter { it.isNotBlank() }.collect { onChangeWord(it) }
+ }
TopAppBar(
title = {
@@ -58,17 +51,21 @@ fun SearchTopBar(
.padding(start = 13.dp),
value = searchWord,
onValueChange = {
- if(it == ""){
+ if (it == "") {
onClearWord()
}
- onChangeWord(it)
+ searchWord = it
},
singleLine = true,
textStyle = TextStyle(
fontSize = 16.sp,
- fontWeight = FontWeight.Normal,fontFamily = pretendard
+ fontWeight = FontWeight.Normal, fontFamily = pretendard
),
- keyboardActions = KeyboardActions(onDone = {onClickSearch()}, onGo = {onClickSearch()}, onSend = {onClickSearch()}, onSearch = {onClickSearch()})
+ keyboardActions = KeyboardActions(
+ onDone = { onClickSearch() },
+ onGo = { onClickSearch() },
+ onSend = { onClickSearch() },
+ onSearch = { onClickSearch() })
) {
Row(
verticalAlignment = Alignment.CenterVertically
@@ -77,7 +74,7 @@ fun SearchTopBar(
Text(
text = "키워드를 검색해보세요",
fontSize = 16.sp,
- style = TextStyle(fontWeight = FontWeight.Normal,fontFamily = pretendard),
+ style = TextStyle(fontWeight = FontWeight.Normal, fontFamily = pretendard),
color = CustomColor.gray3
)
} else {
@@ -158,4 +155,4 @@ fun TestSearchBar() {
navBack = {}
)
}
-}
\ No newline at end of file
+}
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/Spinner.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/Spinner.kt
index 0fd073538..2cc8bc9d1 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/Spinner.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/Spinner.kt
@@ -1,4 +1,4 @@
-package com.hmoa.component
+package com.hmoa.core_designsystem.component
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/SurveyOptionList.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/SurveyOptionList.kt
index b1a5468ef..e5dfc8176 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/SurveyOptionList.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/SurveyOptionList.kt
@@ -1,5 +1,6 @@
package com.hmoa.core_designsystem.component
+import android.util.Log
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
@@ -21,30 +22,58 @@ import com.hmoa.core_designsystem.theme.pretendard
@Composable
fun SurveyOptionList(
- initValue: String? = null,
+ isMutipleAnswerAvailable: Boolean,
+ answerIds: List,
surveyOptions: List,
- onButtonClick: (optionIndex: Int) -> Unit
+ surveyOptionIds: List,
+ onButtonClick: (optionIndex: Int, isGoToSelectedState: Boolean) -> Unit
) {
- val surveyOptions = surveyOptions
- val (selectedOption, onOptionSelected) = remember {
- val idx = if (initValue == null) 0 else surveyOptions.indexOf(initValue)
- mutableStateOf(surveyOptions[idx])
+ val selectedStates = surveyOptionIds.mapIndexed { index, it ->
+ if (it in answerIds) {
+ mutableStateOf(true)
+ } else {
+ mutableStateOf(false)
+ }
+ }
+
+ fun immediateSelectedStateChange(index: Int) {
+ selectedStates[index].value = !selectedStates[index].value
+ }
+
+ fun cancelAllAnswersExceptIndex(index:Int){
+ if (!isMutipleAnswerAvailable) {
+ selectedStates.mapIndexed { idx, mutableState ->
+ if (mutableState.value && idx != index){
+ immediateSelectedStateChange(idx)
+ }
+ }
+ }
}
+
+ fun handleAnswerSelectedState(index: Int) {
+ val state = selectedStates[index].value
+ immediateSelectedStateChange(index)
+ onButtonClick(index, !state)
+ cancelAllAnswersExceptIndex(index)
+ }
+
val scrollState = rememberScrollState()
+
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Top,
- modifier = Modifier.fillMaxHeight(0.7f).verticalScroll(scrollState).background(color =Color.White)
+ modifier = Modifier.fillMaxHeight(0.92f).verticalScroll(scrollState).background(color = Color.White)
) {
surveyOptions.forEachIndexed { index, it ->
Column(modifier = Modifier.padding(bottom = 16.dp)) {
SurveyOptionItem(
- text = it,
- onClick = {
- onOptionSelected(it)
- onButtonClick(index)
- },
- isSelected = (it == selectedOption)
+ text = surveyOptions[index],
+ onClick = { handleAnswerSelectedState(index) },
+ isSelected = try {
+ selectedStates[index].value
+ }catch (e:IndexOutOfBoundsException){
+ false
+ }
)
}
}
@@ -85,9 +114,12 @@ fun SurveyOptionItem(text: String, onClick: () -> Unit, isSelected: Boolean) {
@Preview
@Composable
fun SurveyOptionItemPreview() {
- val seasons = listOf("싱그럽고 활기찬 '봄'", "화창하고 에너지 넘치는 '여름'", "우아하고 고요한 분위기의 '가을'", "차가움과 아늑함이 공존하는 '겨울'")
- Column(verticalArrangement = Arrangement.Bottom, modifier = Modifier.fillMaxHeight(1f).background(color = Color.Yellow)) {
- SurveyOptionList(null, seasons, {})
+ val seasons = listOf("싱그럽고 활기찬 '봄'", "화창하고 에너지 넘치는 '여름'", "우아하고 고요한 분위기의 '가을'", "차가움과 아늑함이 공존하는 '겨울'","싱그럽고 활기찬 '봄'", "화창하고 에너지 넘치는 '여름'", "우아하고 고요한 분위기의 '가을'", "차가움과 아늑함이 공존하는 '겨울'","싱그럽고 활기찬 '봄'", "화창하고 에너지 넘치는 '여름'", "우아하고 고요한 분위기의 '가을'", "차가움과 아늑함이 공존하는 '겨울'")
+ Column(
+ verticalArrangement = Arrangement.Bottom,
+ modifier = Modifier.fillMaxHeight(1f)
+ ) {
+ SurveyOptionList(isMutipleAnswerAvailable = true, answerIds = listOf(), surveyOptions = seasons, surveyOptionIds = listOf(5, 1, 2, 3), onButtonClick = { idx, isGoTo -> })
Button(
isEnabled = true,
btnText = "다음",
@@ -98,4 +130,4 @@ fun SurveyOptionItemPreview() {
radious = 5
)
}
-}
\ No newline at end of file
+}
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/TagBadge.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/TagBadge.kt
index ce2c721f2..bc6a914a0 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/TagBadge.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/TagBadge.kt
@@ -13,6 +13,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
@@ -25,18 +26,20 @@ import com.hmoa.core_designsystem.theme.pretendard
@Composable
fun TagBadge(
height : Dp = 28.dp,
- backgroundColor : Color = Color.White,
- textColor : Color = CustomColor.gray3,
tag : String,
isClickable : Boolean = false,
+ isSelected:Boolean? = false,
onClick : (String) -> Unit = {},
){
+ val backgroundColor = if (isSelected?:true) Color.Black else Color.White
+ val borderColor = if (isSelected?:true) Color.Black else CustomColor.gray3
+ val textColor = if (isSelected?:true) Color.White else Color.Black
Text(
modifier = Modifier
.wrapContentWidth()
.height(height)
.background(color = backgroundColor, shape = RoundedCornerShape(14.dp))
- .border(width = 1.dp, color = CustomColor.gray3, shape = RoundedCornerShape(14.dp))
+ .border(width = 1.dp, color = borderColor, shape = RoundedCornerShape(14.dp))
.then(
if (isClickable) {
Modifier.clickable{onClick(tag)}
@@ -44,13 +47,13 @@ fun TagBadge(
Modifier
}
)
- .padding(horizontal = 14.dp, vertical = 8.dp),
+ .padding(horizontal = 14.dp).padding(top = 8.dp, bottom = 8.dp),
text = tag,
fontSize = 12.sp,
fontFamily = pretendard,
fontWeight = FontWeight.Normal,
color = textColor,
- textAlign = TextAlign.Center
+ textAlign = TextAlign.Center,
)
}
@@ -62,6 +65,8 @@ fun TestMagazineTag(){
.fillMaxSize()
.background(color = Color.White)
){
- TagBadge(tag = "#Test", isClickable = true)
+ TagBadge(tag = "#매거진", isClickable = true)
+ TagBadge(tag = "#HBTI", isClickable = false, isSelected = true)
+ TagBadge(tag = "#HBTI", isClickable = false, isSelected = false)
}
}
\ No newline at end of file
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/TopBar.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/TopBar.kt
index 385cb7375..62fc1e995 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/TopBar.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/TopBar.kt
@@ -1,13 +1,8 @@
-package com.hmoa.component
+package com.hmoa.core_designsystem.component
+import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.*
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -23,31 +18,35 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.hmoa.core_designsystem.R
import com.hmoa.core_designsystem.theme.CustomColor
-import com.hmoa.core_designsystem.theme.pretendard
+import com.hmoa.core_designsystem.theme.CustomFont
@Composable
fun TopBar(
- iconSize : Dp = 20.dp, //icon 크기
- navIcon : Painter ?= null, //navigation 버튼
- onNavClick : () -> Unit = {}, //navigation click 이벤트
- menuIcon : Painter ?= null, //menu 버튼
- onMenuClick : () -> Unit = {}, //menu click 이벤트,
+ color: Color = Color.Transparent,
+ iconSize: Dp = 20.dp, //icon 크기
+ navIcon: Painter? = null, //navigation 버튼
+ onNavClick: () -> Unit = {}, //navigation click 이벤트
+ navIconColor: Color = Color.Black,
+ menuIcon: Painter? = null, //menu 버튼
+ onMenuClick: () -> Unit = {}, //menu click 이벤트,
menuIconColor: Color = CustomColor.black,
- title : String, //메인 타이틀
- titleColor : Color = Color.Black, //타이틀 글 색
-){
+ title: String, //메인 타이틀
+ titleColor: Color = Color.Black, //타이틀 글 색
+) {
Row(
modifier = Modifier
.fillMaxWidth()
.height(60.dp)
+ .background(color = color)
.padding(horizontal = 16.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
- ){
- if (navIcon != null){
+ ) {
+ if (navIcon != null) {
Icon(
modifier = Modifier.size(iconSize).clickable { onNavClick() },
painter = navIcon,
+ tint = navIconColor,
contentDescription = "Navigation Button"
)
} else {
@@ -61,7 +60,7 @@ fun TopBar(
fontSize = 20.sp,
color = titleColor,
fontWeight = FontWeight.Normal,
- fontFamily = pretendard
+ fontFamily = CustomFont.regular
)
Spacer(Modifier.weight(1f))
@@ -81,14 +80,14 @@ fun TopBar(
@Composable
@Preview(showBackground = true)
-fun TopBarPreview(){
+fun TopBarPreview() {
TopBar(
title = "댓글",
iconSize = 25.dp,
navIcon = painterResource(R.drawable.ic_back),
- onNavClick = { },
+ onNavClick = { },
menuIcon = painterResource(R.drawable.three_dot_menu_horizontal),
onMenuClick = {},
menuIconColor = CustomColor.gray2
)
-}
\ No newline at end of file
+}
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/TypeBadge.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/TypeBadge.kt
index 3058cede6..8ee360b86 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/TypeBadge.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/TypeBadge.kt
@@ -35,7 +35,7 @@ fun TypeBadge(
unSelectedIcon: Painter? = null,
iconColor: Color? = null,
selectedColor: Color = Color.Black,
- unSelectedColor: Color = CustomColor.gray2
+ unSelectedColor: Color = CustomColor.gray2,
) {
val fontStyle = TextStyle(
fontSize = fontSize,
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/VerticalStepBar.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/VerticalStepBar.kt
index 740ea29db..9fc274426 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/VerticalStepBar.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/VerticalStepBar.kt
@@ -18,7 +18,7 @@ import com.hmoa.core_designsystem.theme.CustomColor
import com.hmoa.core_designsystem.theme.pretendard
@Composable
-fun VerticalStepBar(titles: Array, contents: Array) {
+fun VerticalStepBar(titles: List, contents: List) {
Column(verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.Start) {
titles.forEachIndexed { index, s ->
Row(verticalAlignment = Alignment.CenterVertically) {
@@ -55,7 +55,12 @@ fun VerticalStepBar(titles: Array, contents: Array) {
}
Text(
contents[index],
- style = TextStyle(fontSize = 12.sp, color = CustomColor.gray5,fontFamily = pretendard, fontWeight = FontWeight.Normal),
+ style = TextStyle(
+ fontSize = 12.sp,
+ color = CustomColor.gray5,
+ fontFamily = pretendard,
+ fontWeight = FontWeight.Normal
+ ),
modifier = Modifier.padding(start = 22.dp, top = 6.dp)
)
}
@@ -67,7 +72,7 @@ fun VerticalStepBar(titles: Array, contents: Array) {
@Composable
fun VerticalStepBarPreview() {
VerticalStepBar(
- arrayOf("향료 선택", "배송", "향수 추천"),
- arrayOf("향BTI 검사 이후 추천하는 향료, 원하는 향료 선택(가격대 상이)", "결제 후 1~2일 내 배송 완료", "시향 후 가장 좋았던 향료 선택, 향수 추천 받기")
+ listOf("향료 선택", "배송", "향수 추천"),
+ listOf("향BTI 검사 이후 추천하는 향료, 원하는 향료 선택(가격대 상이)", "결제 후 1~2일 내 배송 완료", "시향 후 가장 좋았던 향료 선택, 향수 추천 받기")
)
-}
\ No newline at end of file
+}
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/YearPickerDialog.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/YearPickerDialog.kt
index e6e29e7b2..158e4df60 100644
--- a/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/YearPickerDialog.kt
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/YearPickerDialog.kt
@@ -1,4 +1,4 @@
-package com.hmoa.component
+package com.hmoa.core_designsystem.component
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
diff --git a/core-designsystem/src/main/java/com/hmoa/core_designsystem/theme/CustomFont.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/theme/CustomFont.kt
new file mode 100644
index 000000000..93ce2922b
--- /dev/null
+++ b/core-designsystem/src/main/java/com/hmoa/core_designsystem/theme/CustomFont.kt
@@ -0,0 +1,17 @@
+package com.hmoa.core_designsystem.theme
+
+import androidx.compose.ui.text.font.Font
+import androidx.compose.ui.text.font.FontFamily
+import com.hmoa.core_designsystem.R
+
+object CustomFont {
+ val regular = FontFamily(Font(R.font.pretendard_regular))
+ val bold = FontFamily(Font(R.font.pretendard_bold))
+ val thin = FontFamily(Font(R.font.pretendard_thin))
+ val light = FontFamily(Font(R.font.pretendard_light))
+ val black = FontFamily(Font(R.font.pretendard_black))
+ val extraLight = FontFamily(Font(R.font.pretendard_extra_light))
+ val extraBold = FontFamily(Font(R.font.pretendard_extra_bold))
+ val semiBold = FontFamily(Font(R.font.pretendard_semi_bold))
+ val medium = FontFamily(Font(R.font.pretendard_medium))
+}
\ No newline at end of file
diff --git a/core-designsystem/src/main/res/drawable/hmoa.gif b/core-designsystem/src/main/res/drawable/hmoa.gif
new file mode 100644
index 000000000..15e32e596
Binary files /dev/null and b/core-designsystem/src/main/res/drawable/hmoa.gif differ
diff --git a/core-designsystem/src/main/res/drawable/ic_check_not_have_background.xml b/core-designsystem/src/main/res/drawable/ic_check_not_have_background.xml
new file mode 100644
index 000000000..f14dbadd4
--- /dev/null
+++ b/core-designsystem/src/main/res/drawable/ic_check_not_have_background.xml
@@ -0,0 +1,13 @@
+
+
+
diff --git a/core-designsystem/src/main/res/drawable/ic_vertical_three_dot_menu.xml b/core-designsystem/src/main/res/drawable/ic_vertical_three_dot_menu.xml
new file mode 100644
index 000000000..e8b7fa06c
--- /dev/null
+++ b/core-designsystem/src/main/res/drawable/ic_vertical_three_dot_menu.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
diff --git a/core-domain/build.gradle.kts b/core-domain/build.gradle.kts
index 12afbf2bf..bb2d85857 100644
--- a/core-domain/build.gradle.kts
+++ b/core-domain/build.gradle.kts
@@ -1,8 +1,7 @@
plugins {
- id("com.android.library")
- id("org.jetbrains.kotlin.android")
- id("dagger.hilt.android.plugin")
- id("com.google.dagger.hilt.android")
+ alias(libs.plugins.android.library)
+ alias(libs.plugins.kotlin.android)
+ alias(libs.plugins.hilt.android)
kotlin("kapt")
}
@@ -34,17 +33,13 @@ android {
dependencies {
implementation(project(":core-model"))
- val hilt_version = "2.48.1"
- implementation("com.google.dagger:hilt-android:$hilt_version")
- implementation("com.google.dagger:hilt-compiler:$hilt_version")
- testAnnotationProcessor("com.google.dagger:hilt-compiler:$hilt_version")
- kapt("com.google.dagger:hilt-android-compiler:$hilt_version")
+ implementation(libs.bundles.hilt)
+ testAnnotationProcessor(libs.hilt.compiler)
+ kapt(libs.hilt.android.compiler)
- implementation("androidx.core:core-ktx:1.9.0")
- implementation("androidx.appcompat:appcompat:1.6.1")
- implementation("com.google.android.material:material:1.11.0")
- testImplementation("junit:junit:4.13.2")
- androidTestImplementation("androidx.test.ext:junit:1.1.5")
- androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
+ implementation(libs.bundles.basic)
+ testImplementation(libs.junit)
+ androidTestImplementation(libs.junit.ext)
+ androidTestImplementation(libs.espresso)
}
\ No newline at end of file
diff --git a/core-model/src/main/java/com/hmoa/core_model/data/Age.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/Age.kt
similarity index 69%
rename from core-model/src/main/java/com/hmoa/core_model/data/Age.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/data/Age.kt
index 6acbaa7e4..af3dd077d 100644
--- a/core-model/src/main/java/com/hmoa/core_model/data/Age.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/Age.kt
@@ -1,4 +1,4 @@
-package com.hmoa.core_model.data
+package com.hmoa.core_domain.entity.data
enum class Age(val ageNumber: Int) {
AGE10(1), AGE20(2), AGE30(3), AGE40(4), AGE50(5)
diff --git a/feature-home/src/main/java/com/hmoa/feature_home/AllPerfumeScreenId.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/AllPerfumeScreenId.kt
similarity index 59%
rename from feature-home/src/main/java/com/hmoa/feature_home/AllPerfumeScreenId.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/data/AllPerfumeScreenId.kt
index be968d709..b03a2f955 100644
--- a/feature-home/src/main/java/com/hmoa/feature_home/AllPerfumeScreenId.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/AllPerfumeScreenId.kt
@@ -1,4 +1,4 @@
-package com.hmoa.feature_home
+package com.hmoa.core_domain.entity.data
enum class AllPerfumeScreenId {
First, Second, Third
diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/ColumnData.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/ColumnData.kt
similarity index 66%
rename from feature-userInfo/src/main/java/com/hmoa/feature_userinfo/ColumnData.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/data/ColumnData.kt
index e81b56888..bfcfa6bee 100644
--- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/ColumnData.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/ColumnData.kt
@@ -1,4 +1,4 @@
-package com.hmoa.feature_userinfo
+package com.hmoa.core_domain.entity.data
data class ColumnData(
val title : String,
diff --git a/core-model/src/main/java/com/hmoa/core_model/data/Consonant.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/Consonant.kt
similarity index 87%
rename from core-model/src/main/java/com/hmoa/core_model/data/Consonant.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/data/Consonant.kt
index f12975014..a7907fd01 100644
--- a/core-model/src/main/java/com/hmoa/core_model/data/Consonant.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/Consonant.kt
@@ -1,4 +1,4 @@
-package com.hmoa.core_model.data
+package com.hmoa.core_domain.entity.data
enum class Consonant(val id: Int) {
ㄱ(1),
diff --git a/core-domain/src/main/java/com/hmoa/core_domain/entity/data/HbtiQuestionItem.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/HbtiQuestionItem.kt
new file mode 100644
index 000000000..d6047b7d0
--- /dev/null
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/HbtiQuestionItem.kt
@@ -0,0 +1,10 @@
+package com.hmoa.core_domain.entity.data
+
+data class HbtiQuestionItem(
+ val questionId: Int,
+ val questionContent:String,
+ val optionIds: List,
+ val optionContents: List,
+ val isMultipleChoice: Boolean,
+ val selectedOptionIds: MutableList
+)
\ No newline at end of file
diff --git a/core-domain/src/main/java/com/hmoa/core_domain/entity/data/HbtiQuestionItems.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/HbtiQuestionItems.kt
new file mode 100644
index 000000000..acaf63dc2
--- /dev/null
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/HbtiQuestionItems.kt
@@ -0,0 +1,8 @@
+package com.hmoa.core_domain.entity.data
+
+typealias QuestionPageIndex = Int
+
+data class HbtiQuestionItems(
+ val hbtiQuestions: MutableMap,
+ val questionCounts: Int
+)
diff --git a/core-model/src/main/java/com/hmoa/core_model/data/HpediaType.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/HpediaType.kt
similarity index 70%
rename from core-model/src/main/java/com/hmoa/core_model/data/HpediaType.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/data/HpediaType.kt
index 688ae1688..07fc3ee46 100644
--- a/core-model/src/main/java/com/hmoa/core_model/data/HpediaType.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/HpediaType.kt
@@ -1,4 +1,4 @@
-package com.hmoa.core_model.data
+package com.hmoa.core_domain.entity.data
enum class HpediaType(val title:String) {
TERM("용어"),NOTE("노트"),PERFUMER("조향사")
diff --git a/core-model/src/main/java/com/hmoa/core_model/data/MagazineContentItem.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/MagazineContentItem.kt
similarity index 76%
rename from core-model/src/main/java/com/hmoa/core_model/data/MagazineContentItem.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/data/MagazineContentItem.kt
index cd790b459..21ef9b823 100644
--- a/core-model/src/main/java/com/hmoa/core_model/data/MagazineContentItem.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/MagazineContentItem.kt
@@ -1,4 +1,4 @@
-package com.hmoa.core_model.data
+package com.hmoa.core_domain.entity.data
data class MagazineContentItem(
var header : String? = null,
diff --git a/core-model/src/main/java/com/hmoa/core_model/data/MagazineSuccessItem.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/MagazineSuccessItem.kt
similarity index 87%
rename from core-model/src/main/java/com/hmoa/core_model/data/MagazineSuccessItem.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/data/MagazineSuccessItem.kt
index 43ea516e8..885d4f68c 100644
--- a/core-model/src/main/java/com/hmoa/core_model/data/MagazineSuccessItem.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/MagazineSuccessItem.kt
@@ -1,4 +1,4 @@
-package com.hmoa.core_model.data
+package com.hmoa.core_domain.entity.data
data class MagazineSuccessItem(
val title : String,
diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/MyPageCategory.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/MyPageCategory.kt
similarity index 57%
rename from feature-userInfo/src/main/java/com/hmoa/feature_userinfo/MyPageCategory.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/data/MyPageCategory.kt
index 2f10d5729..202d2905f 100644
--- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/MyPageCategory.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/MyPageCategory.kt
@@ -1,4 +1,4 @@
-package com.hmoa.feature_userinfo
+package com.hmoa.core_domain.entity.data
enum class MyPageCategory {
향수,
diff --git a/core-domain/src/main/java/com/hmoa/core_domain/entity/data/NoteOrderQuantity.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/NoteOrderQuantity.kt
new file mode 100644
index 000000000..84738b088
--- /dev/null
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/NoteOrderQuantity.kt
@@ -0,0 +1,5 @@
+package com.hmoa.core_domain.entity.data
+
+enum class NoteOrderQuantity(val id: Int, val number: Int?) {
+ TWO(0, 2), FIVE(1, 5), EIGHT(2, 8), NOLIMIT(3, 100)
+}
\ No newline at end of file
diff --git a/core-domain/src/main/java/com/hmoa/core_domain/entity/data/NoteSelect.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/NoteSelect.kt
new file mode 100644
index 000000000..87c7e662a
--- /dev/null
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/NoteSelect.kt
@@ -0,0 +1,8 @@
+package com.hmoa.core_domain.entity.data
+
+data class NoteSelect(
+ val productId: Int,
+ val isSelected: Boolean,
+ val nodeFaceIndex: Int?,
+ val isRecommended: Boolean,
+)
\ No newline at end of file
diff --git a/core-model/src/main/java/com/hmoa/core_model/data/Perfume.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/Perfume.kt
similarity index 93%
rename from core-model/src/main/java/com/hmoa/core_model/data/Perfume.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/data/Perfume.kt
index f1810873d..dc0d55d2c 100644
--- a/core-model/src/main/java/com/hmoa/core_model/data/Perfume.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/Perfume.kt
@@ -1,4 +1,4 @@
-package com.hmoa.core_model.data
+package com.hmoa.core_domain.entity.data
import com.hmoa.core_model.response.PerfumeCommentGetResponseDto
import com.hmoa.core_model.response.PerfumeReviewResponseDto
@@ -8,7 +8,6 @@ data class Perfume(
val brandEnglishName: String?,
val brandKoreanName: String,
val brandId: String,
- val brandImgUrl: String,
val perfumeEnglishName: String,
val perfumeKoreanName: String,
val baseNote: String?,
diff --git a/core-model/src/main/java/com/hmoa/core_model/PerfumeGender.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/PerfumeGender.kt
similarity index 57%
rename from core-model/src/main/java/com/hmoa/core_model/PerfumeGender.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/data/PerfumeGender.kt
index 99599844d..1b4753337 100644
--- a/core-model/src/main/java/com/hmoa/core_model/PerfumeGender.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/PerfumeGender.kt
@@ -1,4 +1,4 @@
-package com.hmoa.core_model
+package com.hmoa.core_domain.entity.data
enum class PerfumeGender {
MALE, FEMALE, NEUTRAL
diff --git a/feature-home/src/main/java/com/hmoa/feature_home/PerfumeSearchViewType.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/PerfumeSearchViewType.kt
similarity index 55%
rename from feature-home/src/main/java/com/hmoa/feature_home/PerfumeSearchViewType.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/data/PerfumeSearchViewType.kt
index 739bf4059..b92307f46 100644
--- a/feature-home/src/main/java/com/hmoa/feature_home/PerfumeSearchViewType.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/PerfumeSearchViewType.kt
@@ -1,4 +1,4 @@
-package com.hmoa.feature_home
+package com.hmoa.core_domain.entity.data
enum class PerfumeSearchViewType {
List, Grid
diff --git a/core-model/src/main/java/com/hmoa/core_model/data/SortType.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/SortType.kt
similarity index 50%
rename from core-model/src/main/java/com/hmoa/core_model/data/SortType.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/data/SortType.kt
index 9dd995030..68b88fc3a 100644
--- a/core-model/src/main/java/com/hmoa/core_model/data/SortType.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/SortType.kt
@@ -1,4 +1,4 @@
-package com.hmoa.core_model.data
+package com.hmoa.core_domain.entity.data
enum class SortType {
LIKE, LATEST
diff --git a/core-model/src/main/java/com/hmoa/core_model/data/Spice.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/Spice.kt
similarity index 66%
rename from core-model/src/main/java/com/hmoa/core_model/data/Spice.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/data/Spice.kt
index 9f4c37dda..02753232c 100644
--- a/core-model/src/main/java/com/hmoa/core_model/data/Spice.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/Spice.kt
@@ -1,4 +1,4 @@
-package com.hmoa.core_model.data
+package com.hmoa.core_domain.entity.data
data class Spice(
val spiceTitle : String,
diff --git a/core-model/src/main/java/com/hmoa/core_model/data/UserInfo.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/UserInfo.kt
similarity index 77%
rename from core-model/src/main/java/com/hmoa/core_model/data/UserInfo.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/data/UserInfo.kt
index 78e3e31a5..2b19f7b96 100644
--- a/core-model/src/main/java/com/hmoa/core_model/data/UserInfo.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/UserInfo.kt
@@ -1,4 +1,4 @@
-package com.hmoa.core_model.data
+package com.hmoa.core_domain.entity.data
data class UserInfo(
val birth: Int,
diff --git a/core-model/src/main/java/com/hmoa/core_model/Weather.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/Weather.kt
similarity index 58%
rename from core-model/src/main/java/com/hmoa/core_model/Weather.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/data/Weather.kt
index d4189519c..dadba68af 100644
--- a/core-model/src/main/java/com/hmoa/core_model/Weather.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/Weather.kt
@@ -1,4 +1,4 @@
-package com.hmoa.core_model
+package com.hmoa.core_domain.entity.data
enum class Weather {
SPRING, SUMMER, AUTUMN, WINTER
diff --git a/core-domain/src/main/java/com/hmoa/core_domain/entity/data/WebviewType.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/WebviewType.kt
new file mode 100644
index 000000000..1674a2b4c
--- /dev/null
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/WebviewType.kt
@@ -0,0 +1,6 @@
+package com.hmoa.core_domain.entity.data
+
+enum class WebviewType {
+ PRIVACY_CONSENT,
+ SHIPPING_REFUND
+}
\ No newline at end of file
diff --git a/feature-authentication/src/main/java/com/hmoa/feature_authentication/navigation/AuthenticationRoute.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/AuthenticationRoute.kt
similarity index 65%
rename from feature-authentication/src/main/java/com/hmoa/feature_authentication/navigation/AuthenticationRoute.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/AuthenticationRoute.kt
index 15abc650b..2e15f40c4 100644
--- a/feature-authentication/src/main/java/com/hmoa/feature_authentication/navigation/AuthenticationRoute.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/AuthenticationRoute.kt
@@ -1,4 +1,4 @@
-package com.hmoa.feature_authentication.navigation
+package com.hmoa.core_domain.entity.navigation
enum class AuthenticationRoute {
Login,
diff --git a/feature-brand/src/main/java/com/hmoa/feature_brand/navigation/BrandRoute.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/BrandRoute.kt
similarity index 53%
rename from feature-brand/src/main/java/com/hmoa/feature_brand/navigation/BrandRoute.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/BrandRoute.kt
index abb1b9a97..789ad208b 100644
--- a/feature-brand/src/main/java/com/hmoa/feature_brand/navigation/BrandRoute.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/BrandRoute.kt
@@ -1,4 +1,4 @@
-package com.hmoa.feature_brand.navigation
+package com.hmoa.core_domain.entity.navigation
enum class BrandRoute {
Brand,
diff --git a/feature-community/src/main/java/com/hmoa/feature_community/Navigation/CommunityRoute.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/CommunityRoute.kt
similarity index 83%
rename from feature-community/src/main/java/com/hmoa/feature_community/Navigation/CommunityRoute.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/CommunityRoute.kt
index 32c99af39..4454a5e1d 100644
--- a/feature-community/src/main/java/com/hmoa/feature_community/Navigation/CommunityRoute.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/CommunityRoute.kt
@@ -1,4 +1,4 @@
-package com.hmoa.feature_community.Navigation
+package com.hmoa.core_domain.entity.navigation
enum class CommunityRoute {
CommunityGraphRoute,
diff --git a/feature-hpedia/src/main/java/com/hmoa/feature_hpedia/Navigation/HPediaRoute.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/HPediaRoute.kt
similarity index 68%
rename from feature-hpedia/src/main/java/com/hmoa/feature_hpedia/Navigation/HPediaRoute.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/HPediaRoute.kt
index d9a1d26c9..5dc51eaa3 100644
--- a/feature-hpedia/src/main/java/com/hmoa/feature_hpedia/Navigation/HPediaRoute.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/HPediaRoute.kt
@@ -1,4 +1,4 @@
-package com.hmoa.feature_hpedia.Navigation
+package com.hmoa.core_domain.entity.navigation
enum class HPediaRoute {
HPediaGraphRoute,
diff --git a/core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/HbtiRoute.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/HbtiRoute.kt
new file mode 100644
index 000000000..f3cde78a6
--- /dev/null
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/HbtiRoute.kt
@@ -0,0 +1,19 @@
+package com.hmoa.core_domain.entity.navigation
+
+enum class HbtiRoute {
+ Hbti,
+ HbtiSurvey,
+ PerfumeRecommendationRoute,
+ PerfumeRecommendationResultRoute,
+ HbtiSurveyResult,
+ HbtiSurveyLoading,
+ HbtiProcess,
+ NotePick,
+ NotePickResultRoute,
+ OrderRoute,
+ OrderResultRoute,
+ AddAddressRoute,
+ WriteReviewRoute,
+ ReviewRoute,
+ EditReviewRoute,
+}
\ No newline at end of file
diff --git a/feature-home/src/main/java/com/hmoa/feature_home/navigation/HomeRoute.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/HomeRoute.kt
similarity index 59%
rename from feature-home/src/main/java/com/hmoa/feature_home/navigation/HomeRoute.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/HomeRoute.kt
index 3ea3d97af..3e5493a13 100644
--- a/feature-home/src/main/java/com/hmoa/feature_home/navigation/HomeRoute.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/HomeRoute.kt
@@ -1,4 +1,4 @@
-package com.hmoa.feature_home.navigation
+package com.hmoa.core_domain.entity.navigation
enum class HomeRoute {
Home,
diff --git a/feature-magazine/src/main/java/com/hmoa/feature_magazine/Navigation/MagazineRoute.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/MagazineRoute.kt
similarity index 58%
rename from feature-magazine/src/main/java/com/hmoa/feature_magazine/Navigation/MagazineRoute.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/MagazineRoute.kt
index 3dfd6279f..decbeca5b 100644
--- a/feature-magazine/src/main/java/com/hmoa/feature_magazine/Navigation/MagazineRoute.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/MagazineRoute.kt
@@ -1,4 +1,4 @@
-package com.hmoa.feature_magazine.Navigation
+package com.hmoa.core_domain.entity.navigation
enum class MagazineRoute {
MagazineDescRoute,
diff --git a/feature-perfume/src/main/java/com/hmoa/feature_perfume/navigation/PerfumeRoute.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/PerfumeRoute.kt
similarity index 75%
rename from feature-perfume/src/main/java/com/hmoa/feature_perfume/navigation/PerfumeRoute.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/PerfumeRoute.kt
index c63b70946..d97a68b5c 100644
--- a/feature-perfume/src/main/java/com/hmoa/feature_perfume/navigation/PerfumeRoute.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/PerfumeRoute.kt
@@ -1,4 +1,4 @@
-package com.hmoa.feature_perfume.navigation
+package com.hmoa.core_domain.entity.navigation
enum class PerfumeRoute {
Perfume,
diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/navigation/UserInfoGraph.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/UserInfoRoute.kt
similarity index 61%
rename from feature-userInfo/src/main/java/com/hmoa/feature_userinfo/navigation/UserInfoGraph.kt
rename to core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/UserInfoRoute.kt
index cb6376657..4500484ee 100644
--- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/navigation/UserInfoGraph.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/UserInfoRoute.kt
@@ -1,15 +1,20 @@
-package com.example.feature_userinfo
+package com.hmoa.core_domain.entity.navigation
-enum class UserInfoGraph {
+enum class UserInfoRoute {
UserInfoGraph,
MyPage, //마이페이지 Route
NoAuthMyPage, //인증되지 않았을 경우의 화면
MyActivityRoute, //내 활동 화면
MyCommentRoute, //작성한 댓글 Route
MyPostRoute, //작성한 게시글 화면
+ MyReview, //작성한 리뷰
MyFavoriteCommentRoute, //좋아요 누른 댓글 화면
+ MyFavoritePerfumeRoute, //좋아요 한 향수 화면
EditProfileRoute, //프로필 수정 화면
MyInfoRoute, //내 정보 화면
MyBirthRoute, //출생연도 화면
MyGenderRoute, //성별 화면
+ OrderRecordRoute, //주문 내역
+ RefundRoute, //환불 & 반품 화면
+ RefundRecordRoute, //환불 & 반품 내역 화면
}
\ No newline at end of file
diff --git a/core-domain/src/main/java/com/hmoa/core_domain/repository/BootpayRepository.kt b/core-domain/src/main/java/com/hmoa/core_domain/repository/BootpayRepository.kt
new file mode 100644
index 000000000..bc3e28641
--- /dev/null
+++ b/core-domain/src/main/java/com/hmoa/core_domain/repository/BootpayRepository.kt
@@ -0,0 +1,13 @@
+package com.hmoa.core_domain.repository
+
+import ResultResponse
+import com.hmoa.core_model.request.CancelBootpayRequestDto
+import com.hmoa.core_model.request.ConfirmBootpayRequestDto
+import com.hmoa.core_model.response.BootpayOrderResultData
+import com.hmoa.core_model.response.DataResponseDto
+
+interface BootpayRepository {
+ suspend fun postConfirm(requestDto: ConfirmBootpayRequestDto): ResultResponse>
+ suspend fun postCancel(requestDto: CancelBootpayRequestDto): ResultResponse>
+ suspend fun deleteOrder(orderId: Int): ResultResponse>
+}
\ No newline at end of file
diff --git a/core-domain/src/main/java/com/hmoa/core_domain/repository/HShopReviewRepository.kt b/core-domain/src/main/java/com/hmoa/core_domain/repository/HShopReviewRepository.kt
new file mode 100644
index 000000000..fda728093
--- /dev/null
+++ b/core-domain/src/main/java/com/hmoa/core_domain/repository/HShopReviewRepository.kt
@@ -0,0 +1,26 @@
+package com.hmoa.core_domain.repository
+
+import ResultResponse
+import com.hmoa.core_model.response.PagingData
+import com.hmoa.core_model.response.ReviewResponseDto
+import java.io.File
+
+interface HShopReviewRepository {
+ suspend fun getReviews(page: Int): ResultResponse>
+ suspend fun postReview(
+ image: Array,
+ orderId: Int,
+ content: String,
+ ): ResultResponse
+ suspend fun getReview(reviewId: Int): ResultResponse
+ suspend fun postEditReview(
+ image: Array,
+ deleteReviewPhotoIds: Array,
+ content: String,
+ reviewId: Int
+ ): ResultResponse
+ suspend fun deleteReview(reviewId: Int): ResultResponse
+ suspend fun putReviewLike(reviewId: Int): ResultResponse
+ suspend fun deleteReviewLike(reviewId: Int): ResultResponse
+ suspend fun getMyReviews(cursor: Int): ResultResponse>
+}
\ No newline at end of file
diff --git a/core-domain/src/main/java/com/hmoa/core_domain/repository/HshopRepository.kt b/core-domain/src/main/java/com/hmoa/core_domain/repository/HshopRepository.kt
index 10542698e..83b355b74 100644
--- a/core-domain/src/main/java/com/hmoa/core_domain/repository/HshopRepository.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/repository/HshopRepository.kt
@@ -2,9 +2,15 @@ package com.hmoa.core_domain.repository
import ResultResponse
import com.hmoa.core_model.request.ProductListRequestDto
-import com.hmoa.core_model.response.ProductListResponseDto
+import com.hmoa.core_model.response.*
interface HshopRepository {
+ suspend fun getCart(): ResultResponse
suspend fun getNotesProduct(): ResultResponse
- suspend fun postNotesSelected(notes: ProductListRequestDto): ResultResponse
-}
\ No newline at end of file
+ suspend fun postNoteOrder(dto: ProductListRequestDto): ResultResponse
+ suspend fun postNotesSelected(dto: ProductListRequestDto): ResultResponse
+ suspend fun getFinalOrderResult(orderId: Int): ResultResponse
+ suspend fun deleteNoteInOrder(orderId: Int, productId: Int): ResultResponse
+ suspend fun getMyOrders(): ResultResponse>
+ suspend fun getOrderDescriptions(): ResultResponse
+}
diff --git a/core-domain/src/main/java/com/hmoa/core_domain/repository/LoginRepository.kt b/core-domain/src/main/java/com/hmoa/core_domain/repository/LoginRepository.kt
index 803d1c585..01ddda9f6 100644
--- a/core-domain/src/main/java/com/hmoa/core_domain/repository/LoginRepository.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/repository/LoginRepository.kt
@@ -26,5 +26,4 @@ interface LoginRepository {
suspend fun deleteRememberedToken()
suspend fun deleteKakaoAccessToken()
suspend fun deleteGoogleAccessToken()
- suspend fun refreshToken()
}
\ No newline at end of file
diff --git a/core-domain/src/main/java/com/hmoa/core_domain/repository/MemberRepository.kt b/core-domain/src/main/java/com/hmoa/core_domain/repository/MemberRepository.kt
index b5ae8191c..1a78ae128 100644
--- a/core-domain/src/main/java/com/hmoa/core_domain/repository/MemberRepository.kt
+++ b/core-domain/src/main/java/com/hmoa/core_domain/repository/MemberRepository.kt
@@ -1,6 +1,8 @@
package com.hmoa.core_domain.repository
import ResultResponse
+import com.hmoa.core_model.data.DefaultAddressDto
+import com.hmoa.core_model.data.DefaultOrderInfoDto
import com.hmoa.core_model.request.AgeRequestDto
import com.hmoa.core_model.request.JoinUpdateRequestDto
import com.hmoa.core_model.request.NickNameRequestDto
@@ -8,12 +10,17 @@ import com.hmoa.core_model.request.SexRequestDto
import com.hmoa.core_model.response.CommunityByCategoryResponseDto
import com.hmoa.core_model.response.CommunityCommentDefaultResponseDto
import com.hmoa.core_model.response.DataResponseDto
+import com.hmoa.core_model.response.GetRefundRecordResponseDto
import com.hmoa.core_model.response.MemberResponseDto
+import com.hmoa.core_model.response.OrderRecordDto
+import com.hmoa.core_model.response.PagingData
import java.io.File
interface MemberRepository {
suspend fun getMember(): ResultResponse
- suspend fun updateAge(request: AgeRequestDto): DataResponseDto
+ suspend fun getAddress(): ResultResponse
+ suspend fun postAddress(request: DefaultAddressDto): ResultResponse>
+ suspend fun updateAge(request: AgeRequestDto): ResultResponse>
suspend fun getCommunities(page: Int): ResultResponse>
suspend fun getCommunityComments(page: Int): ResultResponse>
suspend fun getCommunityFavoriteComments(page: Int): ResultResponse>
@@ -21,9 +28,13 @@ interface MemberRepository {
suspend fun postExistsNickname(request: NickNameRequestDto): ResultResponse
suspend fun updateJoin(request: JoinUpdateRequestDto): ResultResponse
suspend fun updateNickname(request: NickNameRequestDto): ResultResponse>
+ suspend fun getOrder(cursor: Int): ResultResponse>
+ suspend fun getRefundRecord(cursor: Int): ResultResponse>
+ suspend fun getOrderInfo(): ResultResponse
+ suspend fun postOrderInfo(request: DefaultOrderInfoDto): ResultResponse>
suspend fun getPerfumeComments(page: Int): ResultResponse>
suspend fun getPerfumeFavoriteComments(page: Int): ResultResponse>
suspend fun postProfilePhoto(image: File): ResultResponse>
suspend fun deleteProfilePhoto(): DataResponseDto
- suspend fun updateSex(request: SexRequestDto): DataResponseDto
+ suspend fun updateSex(request: SexRequestDto): ResultResponse