From c030dd32666ed64927e649837af91af2e23ab814 Mon Sep 17 00:00:00 2001 From: Lee YongIn <67788699+LeeYongIn0517@users.noreply.github.com> Date: Sun, 13 Oct 2024 19:05:48 +0900 Subject: [PATCH 01/93] =?UTF-8?q?1.1.2=EB=B2=84=EC=A0=84=20develop=20->=20?= =?UTF-8?q?release=20=EB=A8=B8=EC=A7=80=ED=95=A9=EB=8B=88=EB=8B=A4=20(#168?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Chore: core-common 의존성 추가 * Delete: 토큰 재발급 임시 로직 삭제 * HotFix: Authenticator 토큰 재발급 및 에러메세지 전달 기능 수정 * Fix: Authenticator 적용 * Fix: api 호출부에 Authenticator 적용 * Delete: 안쓰는 api 삭제 * Refactor: FCM 초기화 및 초기 라우팅 코드 함수로 분리 * Delete: 임시 refreshToken 코드 관련 api 삭제 * Rename: 토큰 관련 클래스 의존성 주입 모듈 이름 수정 * Fix: 토큰 동적 할당 시점 변경 * Fix: 로그인 화면 이동 네비게이션 변경 * Chore: 버전 변경 (v1.1.1 -> v1.1.2) * Chore: ci,cd 구문 변경 및 action.yml 파일 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 * Chore: ci/cd 워크플로우 임시로 주석처리 및 사용중지 * Chore: CI 구문 롤백 및 오작동 CI/CD 임시폴더로 분리 * Fix: 파라미터 명시적으로 구분 * Fix: RouteScreen 파라미터 변수명 변경 반영 * Chore: 버전코드 수정 22->23 * Ignore * Fix: 백업데이터 설정 해제 * Chore: 버전 업데이트 * Revert "Chore: 버전 업데이트" This reverts commit 031fc2f141d3ffbc07b0954eda874c58d7e1c834. * Revert "Fix: 백업데이터 설정 해제" This reverts commit bb68a8d265be89d74bcc2feed66baca5355cd475. --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> --- .idea/deploymentTargetSelector.xml | 8 + .idea/other.xml | 11 + app/build.gradle.kts | 4 +- .../main/java/com/hmoa/app/AppViewModel.kt | 19 +- .../main/java/com/hmoa/app/MainActivity.kt | 121 +++++------ .../core_datastore/Admin/AdminDataStore.kt | 12 -- .../Admin/AdminDataStoreImpl.kt | 30 --- .../core_datastore/Brand/BrandDataStore.kt | 3 - .../Brand/BrandDataStoreImpl.kt | 56 ++--- .../BrandHPedia/BrandHPediaDataStore.kt | 10 +- .../BrandHPedia/BrandHPediaDataStoreImpl.kt | 12 -- .../Community/CommunityDataStoreImpl.kt | 100 +++++++-- .../CommunityCommentDataStoreImpl.kt | 92 ++++++--- .../hmoa/core_datastore/DatastoreModule.kt | 5 - .../Fcm/FcmRemoteDataStoreImpl.kt | 53 +++-- .../Hshop/HshopRemoteDataStoreImpl.kt | 26 ++- .../Login/LoginRemoteDataStoreImpl.kt | 29 +-- .../Magazine/MagazineDataStoreImpl.kt | 67 ++++-- .../core_datastore/Main/MainDataStoreImpl.kt | 52 +++-- .../Member/MemberDataStoreImpl.kt | 193 ++++++++++++------ .../core_datastore/Note/NoteDataStoreImpl.kt | 24 ++- .../Perfume/PerfumeDataStoreImpl.kt | 95 ++++++--- .../PerfumeCommentDataStoreImpl.kt | 47 ++++- .../Perfumer/PerfumerDataStoreImpl.kt | 17 +- .../Report/ReportDataStoreImpl.kt | 17 +- .../Search/SearchDataStoreImpl.kt | 52 +++-- .../Survey/SurveyRemoteDataStoreImpl.kt | 72 +++++-- .../core_datastore/Term/TermDataStoreImpl.kt | 15 +- .../component/ErrorUiSetView.kt | 1 + .../core_domain/repository/AdminRepository.kt | 12 -- .../repository/BrandHPediaRepository.kt | 7 - .../core_domain/repository/BrandRepository.kt | 3 - core-network/build.gradle.kts | 2 +- .../authentication/AuthAuthenticator.kt | 62 ------ .../authentication/Authenticator.kt | 21 ++ .../authentication/AuthenticatorImpl.kt | 93 +++++++++ ...catorModule.kt => AuthenticationModule.kt} | 6 +- .../com/hmoa/core_network/di/ServiceModule.kt | 13 +- .../hmoa/core_network/service/AdminService.kt | 26 --- .../service/BrandHPediaService.kt | 11 - .../hmoa/core_network/service/BrandService.kt | 15 -- .../core_repository/AdminRepositoryImpl.kt | 30 --- .../BrandHPediaRepositoryImpl.kt | 12 -- .../core_repository/BrandRepositoryImpl.kt | 13 -- .../core_repository/LoginRepositoryImpl.kt | 3 - .../hmoa/core_repository/RepositoryModule.kt | 6 +- .../feature_community/Navigation/NavGraph.kt | 60 +++--- .../Screen/CommunityDescriptionPage.kt | 63 +++--- .../feature_community/Screen/CommunityHome.kt | 32 ++- .../Screen/CommunityPreview.kt | 52 ++--- .../feature_hpedia/Screen/HPediaScreen.kt | 6 +- 51 files changed, 1022 insertions(+), 769 deletions(-) delete mode 100644 core-datastore/src/main/java/com/hmoa/core_datastore/Admin/AdminDataStore.kt delete mode 100644 core-datastore/src/main/java/com/hmoa/core_datastore/Admin/AdminDataStoreImpl.kt delete mode 100644 core-domain/src/main/java/com/hmoa/core_domain/repository/AdminRepository.kt delete mode 100644 core-network/src/main/java/com/hmoa/core_network/authentication/AuthAuthenticator.kt create mode 100644 core-network/src/main/java/com/hmoa/core_network/authentication/Authenticator.kt create mode 100644 core-network/src/main/java/com/hmoa/core_network/authentication/AuthenticatorImpl.kt rename core-network/src/main/java/com/hmoa/core_network/di/{AuthenticatorModule.kt => AuthenticationModule.kt} (80%) delete mode 100644 core-network/src/main/java/com/hmoa/core_network/service/AdminService.kt delete mode 100644 core-repository/src/main/java/com/hmoa/core_repository/AdminRepositoryImpl.kt diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml index b268ef36c..70faf41cc 100644 --- a/.idea/deploymentTargetSelector.xml +++ b/.idea/deploymentTargetSelector.xml @@ -4,6 +4,14 @@ diff --git a/.idea/other.xml b/.idea/other.xml index 94c96f631..a76f1180a 100644 --- a/.idea/other.xml +++ b/.idea/other.xml @@ -25,6 +25,17 @@ From 6a5f790059d0aebfd4fdea7a5158498471796071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Wed, 6 Nov 2024 14:22:44 +0900 Subject: [PATCH 14/93] =?UTF-8?q?chore:=20=EC=A3=BC=EC=84=9D=ED=95=B4?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/hmoa/feature_hbti/viewmodel/HbtiHomeViewModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiHomeViewModel.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiHomeViewModel.kt index 37fd37cf8..7ae7c10a5 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiHomeViewModel.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiHomeViewModel.kt @@ -61,7 +61,7 @@ class HbtiHomeViewModel @Inject constructor( ) init { - //getMetaData() + getMetaData() getReviews() checkIsLogined() } From 3c76629c5b8430e55cd99b2b56a72b49d0b877e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Wed, 6 Nov 2024 15:26:16 +0900 Subject: [PATCH 15/93] =?UTF-8?q?Feat:=20=EC=83=81=ED=92=88=20=EA=B5=AC?= =?UTF-8?q?=EB=A7=A4=20=EC=97=AC=EB=B6=80=20=ED=99=95=EC=9D=B8=20=EB=8B=A4?= =?UTF-8?q?=EC=9D=B4=EC=96=BC=EB=A1=9C=EA=B7=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../response/HbtiHomeMetaDataResponse.kt | 2 +- .../core_network/service/SurveyService.kt | 2 +- .../hmoa/feature_hbti/screen/HbtiScreen.kt | 158 +++++++++++------- .../viewmodel/HbtiHomeViewModel.kt | 29 ++-- 4 files changed, 116 insertions(+), 75 deletions(-) diff --git a/core-model/src/main/java/com/hmoa/core_model/response/HbtiHomeMetaDataResponse.kt b/core-model/src/main/java/com/hmoa/core_model/response/HbtiHomeMetaDataResponse.kt index 5d2d2a1cf..9c67ce192 100644 --- a/core-model/src/main/java/com/hmoa/core_model/response/HbtiHomeMetaDataResponse.kt +++ b/core-model/src/main/java/com/hmoa/core_model/response/HbtiHomeMetaDataResponse.kt @@ -6,6 +6,6 @@ import kotlinx.serialization.Serializable data class HbtiHomeMetaDataResponse( val backgroundImgUrl: String, val firstImageUrl: String, + val isOrdered: Boolean, val secondImageUrl: String, - val isOrdered: Boolean ) diff --git a/core-network/src/main/java/com/hmoa/core_network/service/SurveyService.kt b/core-network/src/main/java/com/hmoa/core_network/service/SurveyService.kt index 06f981c59..3a6902186 100644 --- a/core-network/src/main/java/com/hmoa/core_network/service/SurveyService.kt +++ b/core-network/src/main/java/com/hmoa/core_network/service/SurveyService.kt @@ -40,5 +40,5 @@ interface SurveyService { ): ApiResponse @GET("/survey/home") - fun getHbtiHomeMetaData(): ApiResponse + suspend fun getHbtiHomeMetaData(): ApiResponse } \ No newline at end of file diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiScreen.kt index 75a597fc7..84b4b2a49 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiScreen.kt @@ -18,6 +18,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight @@ -51,6 +52,7 @@ fun HbtiRoute( ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() val errState by viewModel.errorUiState.collectAsStateWithLifecycle() + val isOrderWarninngNeeded by viewModel.isOrderedWarningNeedState.collectAsStateWithLifecycle() HbtiScreen( onHbtiSurveyClick = { onHbtiSurveyClick() }, onAfterOrderClick = { viewModel::onAfterOrderClick { onAfterOrderClick() } }, @@ -60,8 +62,10 @@ fun HbtiRoute( navEditReview = navEditReview, onDeleteClick = viewModel::deleteReview, onReportClick = viewModel::reportReview, + onAfterOrderWarningDialogClick = viewModel::initializeIsOrderWarningNeedState, uiState = uiState, errState = errState, + isOrderWarningNeed = isOrderWarninngNeeded, onHeartClick = viewModel::onHeartClick, navLogin = navLogin ) @@ -70,7 +74,6 @@ fun HbtiRoute( @Composable fun HbtiScreen( onHbtiSurveyClick: () -> Unit, - onAfterOrderClick: () -> Unit, navBack: () -> Unit, navHome: () -> Unit, navLogin: () -> Unit, @@ -78,7 +81,10 @@ fun HbtiScreen( navEditReview: (reviewId: Int) -> Unit, onDeleteClick: (reviewId: Int) -> Unit, onReportClick: (reviewId: Int) -> Unit, + onAfterOrderClick: () -> Unit, + onAfterOrderWarningDialogClick: () -> Unit, uiState: HbtiHomeUiState, + isOrderWarningNeed: Boolean, errState: ErrorUiState, onHeartClick: (reviewId: Int, isLiked: Boolean) -> Unit, ) { @@ -87,6 +93,9 @@ fun HbtiScreen( errorUiState = errState, onCloseClick = navHome ) + + OrderWarningDialog(isOrderWarnNeeded = isOrderWarningNeed, onAfterClick = onAfterOrderWarningDialogClick) + when (uiState) { HbtiHomeUiState.Loading -> AppLoadingScreen() HbtiHomeUiState.Error -> { @@ -109,6 +118,25 @@ fun HbtiScreen( } } +@Composable +private fun OrderWarningDialog(isOrderWarnNeeded: Boolean, onAfterClick: () -> Unit) { + val screenWidth = LocalConfiguration.current.screenWidthDp.dp + AppDesignDialog( + isOpen = isOrderWarnNeeded, + modifier = Modifier.wrapContentHeight() + .width(screenWidth - 88.dp), + title = "주문 후 이용가능한 서비스입니다", + content = "배송 후 후기를 작성해주세요", + buttonTitle = "확인", + onOkClick = { + onAfterClick() + }, + onCloseClick = { + onAfterClick() + } + ) +} + @OptIn(ExperimentalMaterialApi::class) @Composable private fun HbtiHomeContent( @@ -221,7 +249,7 @@ private fun HbtiHomeContent( shape = RoundedCornerShape(5.dp) )) { ImageView( - imageUrl = "https://github.com/HMOAA/HMOA_ANDROID/assets/67788699/122bc5b1-1cc1-44b3-a468-1b56f9998994", + imageUrl = metadata?.firstImageUrl, width = 1f, height = 1f, backgroundColor = Color.Transparent, @@ -259,7 +287,7 @@ private fun HbtiHomeContent( ) ) { ImageView( - imageUrl = "https://github.com/HMOAA/HMOA_ANDROID/assets/67788699/4bb30703-d77d-49ac-8a01-2aee48bf04c3", + imageUrl = metadata?.secondImageUrl, width = 1f, height = 1f, backgroundColor = Color.Transparent, @@ -362,78 +390,82 @@ private fun HbtiHomeContent( @Preview @Composable fun HbtiScreenPreview() { - HbtiScreen({}, {}, errState = ErrorUiState.Loading, uiState = HbtiHomeUiState.Success( - listOf( - ReviewResponseDto( - hbtiReviewId = 0, - profileImgUrl = "", - author = "향수 러버", - content = "향수를 1회도 구매하지 않은 사람인데 향모아에서 인생향수 찾았어요!", - imagesCount = 4, - hbtiPhotos = listOf( - Photo( - photoUrl = "", - photoId = 0 - ), - Photo( - photoUrl = "", - photoId = 0 - ), - Photo( - photoUrl = "", - photoId = 0 - ), - Photo( - photoUrl = "", - photoId = 0 + HbtiScreen( + {}, errState = ErrorUiState.Loading, uiState = HbtiHomeUiState.Success( + listOf( + ReviewResponseDto( + hbtiReviewId = 0, + profileImgUrl = "", + author = "향수 러버", + content = "향수를 1회도 구매하지 않은 사람인데 향모아에서 인생향수 찾았어요!", + imagesCount = 4, + hbtiPhotos = listOf( + Photo( + photoUrl = "", + photoId = 0 + ), + Photo( + photoUrl = "", + photoId = 0 + ), + Photo( + photoUrl = "", + photoId = 0 + ), + Photo( + photoUrl = "", + photoId = 0 + ), ), + createdAt = "10일 전", + isWrited = false, + heartCount = 12, + isLiked = false, + orderTitle = "시트러스" ), - createdAt = "10일 전", - isWrited = false, - heartCount = 12, - isLiked = false, - orderTitle = "시트러스" - ), - ReviewResponseDto( - hbtiReviewId = 0, - profileImgUrl = "", - author = "향수 러버", - content = "평소에 선호하는 향이 있었는데 그 향의 이름을 몰랐는데 향료 배송받고 시향해본 통카 빈? 이더라구요 제가 좋아했던 향수들은 다 통카 빈이 들어가있네요 ㅎ 저 같은 분들에게 추천해요", - imagesCount = 4, - hbtiPhotos = listOf( - Photo( - photoUrl = "", - photoId = 0 - ), - Photo( - photoUrl = "", - photoId = 0 - ), - Photo( - photoUrl = "", - photoId = 0 - ), - Photo( - photoUrl = "", - photoId = 0 + ReviewResponseDto( + hbtiReviewId = 0, + profileImgUrl = "", + author = "향수 러버", + content = "평소에 선호하는 향이 있었는데 그 향의 이름을 몰랐는데 향료 배송받고 시향해본 통카 빈? 이더라구요 제가 좋아했던 향수들은 다 통카 빈이 들어가있네요 ㅎ 저 같은 분들에게 추천해요", + imagesCount = 4, + hbtiPhotos = listOf( + Photo( + photoUrl = "", + photoId = 0 + ), + Photo( + photoUrl = "", + photoId = 0 + ), + Photo( + photoUrl = "", + photoId = 0 + ), + Photo( + photoUrl = "", + photoId = 0 + ), ), + createdAt = "10일 전", + isWrited = false, + heartCount = 12, + isLiked = true, + orderTitle = "시트러스" ), - createdAt = "10일 전", - isWrited = false, - heartCount = 12, - isLiked = true, - orderTitle = "시트러스" ), + null ), - null - ), navBack = {}, navHome = {}, navReview = {}, onHeartClick = { a, b -> }, onReportClick = {}, onDeleteClick = {}, + onAfterOrderClick = {}, + onAfterOrderWarningDialogClick = {}, navEditReview = {}, - navLogin = {} + navLogin = {}, + isOrderWarningNeed = false ) } diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiHomeViewModel.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiHomeViewModel.kt index 7ae7c10a5..6a417e13e 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiHomeViewModel.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiHomeViewModel.kt @@ -27,6 +27,8 @@ class HbtiHomeViewModel @Inject constructor( private val flag = MutableStateFlow(false) private val reviewsState = MutableStateFlow>(listOf()) private val metadataState = MutableStateFlow(null) + private val _isOrderedWarningNeedState = MutableStateFlow(false) + val isOrderedWarningNeedState: StateFlow = _isOrderedWarningNeedState private var expiredTokenErrorState = MutableStateFlow(false) private var wrongTypeTokenErrorState = MutableStateFlow(false) private var unLoginedErrorState = MutableStateFlow(false) @@ -49,16 +51,17 @@ class HbtiHomeViewModel @Inject constructor( initialValue = ErrorUiState.Loading ) - val uiState: StateFlow = combine(reviewsState, metadataState) { _reviews, _metadata -> - HbtiHomeUiState.Success( - reviews = _reviews, - metadata = _metadata + val uiState: StateFlow = + combine(reviewsState, metadataState) { _reviews, _metadata -> + HbtiHomeUiState.Success( + reviews = _reviews, + metadata = _metadata, + ) + }.stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5_000), + initialValue = HbtiHomeUiState.Loading ) - }.stateIn( - scope = viewModelScope, - started = SharingStarted.WhileSubscribed(5_000), - initialValue = HbtiHomeUiState.Loading - ) init { getMetaData() @@ -153,13 +156,19 @@ class HbtiHomeViewModel @Inject constructor( } fun onAfterOrderClick(onAvailable: () -> Unit) { + Log.d("HbtiHomeViewModel", "isOrderedWarningNeedState.value: ${isOrderedWarningNeedState.value}") if (metadataState.value?.isOrdered ?: true) { onAvailable() } else { - TODO("다이얼로그 오픈") + _isOrderedWarningNeedState.update { true } } } + fun initializeIsOrderWarningNeedState() { + _isOrderedWarningNeedState.update { false } + Log.d("HbtiHomeViewModel", "isOrderedWarningNeedState.value: ${isOrderedWarningNeedState.value}") + } + fun reportReview(reviewId: Int) { viewModelScope.launch { val result = reportRepository.reportReview(reviewId) From 9e65cfec9c3ce0a79b7383b4fc623e54bed0e73f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Wed, 6 Nov 2024 20:04:16 +0900 Subject: [PATCH 16/93] =?UTF-8?q?Feat:=20Hbti=20=EC=84=A4=EB=AC=B8=20?= =?UTF-8?q?=EC=96=91=EC=98=86=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/hmoa/core_common/CommonFunctions.kt | 8 ++- .../feature_hbti/screen/HbtiSurveyScreen.kt | 61 +++++++++++++++---- 2 files changed, 55 insertions(+), 14 deletions(-) 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 index a98c3a5ff..7c160db25 100644 --- a/core-common/src/main/java/com/hmoa/core_common/CommonFunctions.kt +++ b/core-common/src/main/java/com/hmoa/core_common/CommonFunctions.kt @@ -27,8 +27,12 @@ fun calculateProgressStepSize(list: List?): Float { } } -fun OrderStatus.toDisplayString(): String{ - return when(this){ +fun calculateHbtiProgressStepSize(list: List?): Float { + return ((100).div(list?.size?.minus(1) ?: 10)).div(100.0).toFloat() +} + +fun OrderStatus.toDisplayString(): String { + return when (this) { OrderStatus.CREATED -> "주문 생성" OrderStatus.PAY_FAILED -> "결제 실패" OrderStatus.PAY_CANCEL -> "환불 완료" diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt index 8f76a772d..79ec9dcab 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt @@ -1,5 +1,6 @@ package com.hmoa.feature_hbti.screen +import android.util.Log import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.layout.* @@ -20,7 +21,7 @@ import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.hmoa.core_common.ErrorUiState -import com.hmoa.core_common.calculateProgressStepSize +import com.hmoa.core_common.calculateHbtiProgressStepSize import com.hmoa.core_designsystem.component.* import com.hmoa.core_designsystem.theme.CustomColor import com.hmoa.core_designsystem.theme.CustomFont @@ -113,12 +114,16 @@ fun HbtiSurveyContent( var targetProgress by remember { mutableStateOf(0f) } val scope = rememberCoroutineScope() // Create a coroutine scope val pageContent = hbtiQuestionItems?.hbtiQuestions?.values?.map { it } - val additionalProgress = calculateProgressStepSize(pageContent) + val additionalProgress = calculateHbtiProgressStepSize(pageContent) val pagerState = rememberPagerState(initialPage = 0, pageCount = { hbtiQuestionItems?.hbtiQuestions?.values?.size ?: 0 }) fun addProgress() { targetProgress += additionalProgress + Log.d( + "HbtiScroll", + "currentProgress: ${currentProgress}, targetProgress: ${targetProgress}, additionalProgress: ${additionalProgress}" + ) scope.launch { loadProgress { progress -> if (currentProgress <= targetProgress) { @@ -139,19 +144,51 @@ fun HbtiSurveyContent( } } + fun preventScrollOver2Pages(currentPage: Int, targetPage: Int) { + if (kotlin.math.abs(targetPage - currentPage) > 1) { + // If trying to move more than one page, cancel and scroll back + scope.launch { pagerState.animateScrollToPage(currentPage) } + } + } + + LaunchedEffect(pagerState) { + snapshotFlow { pagerState.targetPage } + .collect { targetPage -> + Log.d("HbtiScroll", "currentPage:${currentProgress}, targetPage:${targetPage}") + val currentPage = pagerState.currentPage + preventScrollOver2Pages(currentPage, targetPage) + if (currentPage > targetPage) { + subtractProgress() + } else if (currentPage < targetPage) { + addProgress() + } + } + } + + +// LaunchedEffect(pagerState) { +// snapshotFlow { pagerState.currentPage } +// .distinctUntilChanged() +// .collect { currentPage -> +// if (currentPage == previousPage + 1) { +// Log.d("HbtiScroll", "currentPage: ${currentPage}, {previousPage: ${previousPage}") +// addProgress() +// pagerState.animateScrollToPage(pagerState.currentPage + 1) +// +// } else if (currentPage == previousPage - 1) { +// subtractProgress() +// pagerState.animateScrollToPage(pagerState.currentPage - 1) +// } +// } +// } + + Column(modifier = Modifier.fillMaxSize().background(color = Color.White)) { TopBar( title = "향BTI", titleColor = Color.Black, navIcon = painterResource(com.hmoa.core_designsystem.R.drawable.ic_back), - onNavClick = { - if (pagerState.currentPage == 0) { - onBackClick() - } else { - subtractProgress() - scope.launch { pagerState.animateScrollToPage(pagerState.currentPage - 1) } - } - } + onNavClick = onBackClick ) Column( modifier = Modifier.padding(horizontal = 16.dp).padding(bottom = 40.dp).fillMaxHeight(1f), @@ -166,10 +203,10 @@ fun HbtiSurveyContent( Column { ProgressBar(percentage = currentProgress) HorizontalPager( - userScrollEnabled = false, + userScrollEnabled = isNextQuestionAvailable?.get(pagerState.currentPage) ?: true, modifier = Modifier.fillMaxWidth().background(color = Color.White), state = pagerState, - verticalAlignment = Alignment.Top + verticalAlignment = Alignment.Top, ) { page -> Column(verticalArrangement = Arrangement.SpaceBetween) { Column(modifier = Modifier.fillMaxWidth()) { From fc4893e27ae35940bdeadae0e1fd9176d3fcc265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Wed, 6 Nov 2024 20:07:22 +0900 Subject: [PATCH 17/93] =?UTF-8?q?Delete:=20=EC=A3=BC=EC=84=9D=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature_hbti/screen/HbtiSurveyScreen.kt | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt index 79ec9dcab..49aeab22b 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt @@ -1,6 +1,5 @@ package com.hmoa.feature_hbti.screen -import android.util.Log import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.layout.* @@ -120,10 +119,6 @@ fun HbtiSurveyContent( fun addProgress() { targetProgress += additionalProgress - Log.d( - "HbtiScroll", - "currentProgress: ${currentProgress}, targetProgress: ${targetProgress}, additionalProgress: ${additionalProgress}" - ) scope.launch { loadProgress { progress -> if (currentProgress <= targetProgress) { @@ -146,7 +141,6 @@ fun HbtiSurveyContent( fun preventScrollOver2Pages(currentPage: Int, targetPage: Int) { if (kotlin.math.abs(targetPage - currentPage) > 1) { - // If trying to move more than one page, cancel and scroll back scope.launch { pagerState.animateScrollToPage(currentPage) } } } @@ -154,7 +148,6 @@ fun HbtiSurveyContent( LaunchedEffect(pagerState) { snapshotFlow { pagerState.targetPage } .collect { targetPage -> - Log.d("HbtiScroll", "currentPage:${currentProgress}, targetPage:${targetPage}") val currentPage = pagerState.currentPage preventScrollOver2Pages(currentPage, targetPage) if (currentPage > targetPage) { @@ -165,24 +158,6 @@ fun HbtiSurveyContent( } } - -// LaunchedEffect(pagerState) { -// snapshotFlow { pagerState.currentPage } -// .distinctUntilChanged() -// .collect { currentPage -> -// if (currentPage == previousPage + 1) { -// Log.d("HbtiScroll", "currentPage: ${currentPage}, {previousPage: ${previousPage}") -// addProgress() -// pagerState.animateScrollToPage(pagerState.currentPage + 1) -// -// } else if (currentPage == previousPage - 1) { -// subtractProgress() -// pagerState.animateScrollToPage(pagerState.currentPage - 1) -// } -// } -// } - - Column(modifier = Modifier.fillMaxSize().background(color = Color.White)) { TopBar( title = "향BTI", From 62698c299fa5b0e130a93d6b29687bcb8cad0fe5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Wed, 6 Nov 2024 20:50:11 +0900 Subject: [PATCH 18/93] =?UTF-8?q?Fix:=20LazyColumn=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=ED=9B=84=20=EC=8A=A4=ED=81=AC=EB=A1=A4?= =?UTF-8?q?=EC=9C=84=EC=B9=98=20=EC=B4=88=EA=B8=B0=ED=99=94=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hmoa/feature_home/screen/HomeScreen.kt | 107 +++++++++++------- 1 file changed, 66 insertions(+), 41 deletions(-) diff --git a/feature-home/src/main/java/com/hmoa/feature_home/screen/HomeScreen.kt b/feature-home/src/main/java/com/hmoa/feature_home/screen/HomeScreen.kt index 7fbcdbd36..a3bf1f8b0 100644 --- a/feature-home/src/main/java/com/hmoa/feature_home/screen/HomeScreen.kt +++ b/feature-home/src/main/java/com/hmoa/feature_home/screen/HomeScreen.kt @@ -1,9 +1,11 @@ package com.hmoa.feature_home.screen -import androidx.compose.foundation.* +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.lazy.LazyRow -import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.* import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -54,60 +56,83 @@ private fun HomeScreen( ) { val firstMenuWithBannerState by viewModel.firstMenuWithBannerState.collectAsStateWithLifecycle() val bottomMenuState by viewModel.bottomMenuState.collectAsStateWithLifecycle() - val verticalScrollState = rememberScrollState() + val listState = rememberLazyListState() LaunchedEffect(true) { - verticalScrollState.animateScrollTo(10000) + listState.animateScrollToItem(index = 0) } - - Column( + LazyColumn( modifier = Modifier .fillMaxSize() - .verticalScroll(state = verticalScrollState, reverseScrolling = true) .background(Color.White), + horizontalAlignment = Alignment.CenterHorizontally, + state = listState ) { - when (firstMenuWithBannerState) { - is HomeViewModel.BannerWithFirstMenuState.Loading -> { - AppLoadingScreen() - } - is HomeViewModel.BannerWithFirstMenuState.Data -> { - Column( - modifier = Modifier.fillMaxWidth().padding(horizontal = 17.dp).padding(vertical = 10.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center - ) { - FirstMenuWithBannerContent( - onHbtiClick = { onHbtiClick() }, - bannerImgUrl = (firstMenuWithBannerState as HomeViewModel.BannerWithFirstMenuState.Data).bannerImg, - ) - } - FirstMenuView( - (firstMenuWithBannerState as HomeViewModel.BannerWithFirstMenuState.Data).firstMenu!!, - { onPerfumeClick(it) }) + itemsIndexed( + listOf("TopMenu", "BottomMenu") + ) { idx, item -> + when (idx) { + 0 -> TopMenu(firstMenuWithBannerState, onPerfumeClick, onHbtiClick) + 1 -> BottomMenu(bottomMenuState, onPerfumeClick, onAllPerfumeClick) } + } + } - is HomeViewModel.BannerWithFirstMenuState.Error -> { +} - } +@Composable +fun TopMenu( + firstMenuWithBannerState: HomeViewModel.BannerWithFirstMenuState, onPerfumeClick: (perfumeId: Int) -> Unit, + onHbtiClick: () -> Unit, +) { + when (firstMenuWithBannerState) { + is HomeViewModel.BannerWithFirstMenuState.Loading -> { + AppLoadingScreen() } - when (bottomMenuState) { - is HomeViewModel.BottomMenuState.Loading -> { - AppLoadingScreen() - } - - is HomeViewModel.BottomMenuState.Data -> { - BottomMenuContent( - onPerfumeClick = { onPerfumeClick(it) }, - onAllPerfumeClick = { onAllPerfumeClick(it) }, - (bottomMenuState as HomeViewModel.BottomMenuState.Data).bottomMenu!! + is HomeViewModel.BannerWithFirstMenuState.Data -> { + Column( + modifier = Modifier.fillMaxWidth().padding(horizontal = 17.dp).padding(vertical = 10.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + FirstMenuWithBannerContent( + onHbtiClick = { onHbtiClick() }, + bannerImgUrl = (firstMenuWithBannerState as HomeViewModel.BannerWithFirstMenuState.Data).bannerImg, ) - HmoaCompanyMetaData() } + FirstMenuView( + (firstMenuWithBannerState as HomeViewModel.BannerWithFirstMenuState.Data).firstMenu!!, + { onPerfumeClick(it) }) + } - is HomeViewModel.BottomMenuState.Error -> { + is HomeViewModel.BannerWithFirstMenuState.Error -> { + + } + } +} + +@Composable +fun BottomMenu( + bottomMenuState: HomeViewModel.BottomMenuState, onPerfumeClick: (perfumeId: Int) -> Unit, + onAllPerfumeClick: (screenId: AllPerfumeScreenId) -> Unit, +) { + when (bottomMenuState) { + is HomeViewModel.BottomMenuState.Loading -> { + AppLoadingScreen() + } + + is HomeViewModel.BottomMenuState.Data -> { + BottomMenuContent( + onPerfumeClick = { onPerfumeClick(it) }, + onAllPerfumeClick = { onAllPerfumeClick(it) }, + (bottomMenuState as HomeViewModel.BottomMenuState.Data).bottomMenu!! + ) + HmoaCompanyMetaData() + } + + is HomeViewModel.BottomMenuState.Error -> { - } } } } From ad96af9dba4682f44e701d7cdaabb5b31a8d71b6 Mon Sep 17 00:00:00 2001 From: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> Date: Tue, 12 Nov 2024 21:30:20 +0900 Subject: [PATCH 19/93] Feature/hbti shj (#182) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat: 배송 상태 번역 함수 추가 * Fix: 파라미터 타입 변경 (String >> Note) * Feat: api response에 따른 파라미터 타입 변경 * Feat: 주문 내역, 환불 화면 navigation graph에 추가 * Feat: 주문 내역 화면 비즈니스 로직과 연결 * Feat: 환불 신청 화면 비즈니스 로직과 연결 * Feat: 환불 신청 화면 비즈니스 로직 추가 * Feat: 주문 내역 비즈니스 로직 추가 * Fix: 파라미터 변경에 따른 수정 (String >> Note) * Feat: 주문 내역, 환불 화면 route graph에 추가 * Feat: 주문 내역 navigation 이벤트 추가 * Feat: 주문 내역 navigation 이벤트 추가 * Fix: 파라미터 타입 변경 (Not Null >> Nullable) * Fix: filter not 동작 오류 수정 * Fix: 가격 계산 로직 변경 * Fix: 엘비스 연산 처리 추가 * Fix: 파라미터 matching 실수 수정 * Design: 여백 조정 * Rename: 파라미터 명 변경 * Feat: 환불 api 완료 후에 이전 화면으로 navigation 되도록 설정 * Feat: 가격 계산 관련 비즈니스 로직 수정 * Comment: Log 삭제 * Feat: Web Link 연결에서 Web View 사용으로 변경 * Remove: 미사용 UI 삭제 * Feat: 파라미터 타입 변경 (not null >> nullable) * Feat: 파라미터 값 null 여부에 따른 UI 분기 * Rename: navigation route 클래스 위치 이동 (각 feature 모듈 >> core-domain.entity) * Rename: navigation route 클래스 위치 이동 (각 feature 모듈 >> core-domain.entity) * Rename: navigation 이벤트 명 변경 * Rename: navigation 이벤트 명 변경 * Rename: navigation 이벤트 명 변경 * Rename: entity 위치 변경 (각 feature 모듈 & core-model >> core-domain) * Feat: decode from string import 누락 추가 * Feat: decode from string import 누락 추가 * Feat: 주문 내역 조회 paging 처리 * Feat: nullable 처리 * Rename: 파라미터 명 변경 * Chore: 의존성 중복 제거 * Rename: 파라미터 이름 변경 * Fix: 파라미터 변경 * Rename: navigation 이벤트 명 변경 * Rename: 화면 명 변경 * Feat: 환불/반품 내역 조회 api 추가 * Rename: 함수 이름 변경 (getRefund >> getRefundRecord) * Rename: 함수 이름 변경 (getFavoriteCommentPaging >> getOrderRecordPaging) * Rename: 파일 명 변경 (ReturnOrRefundRecordPage >> RefundRecordPage) * Feat: 반품/환불 내역 비즈니스 로직 추가 * Feat: Empty Data Page 컴포넌트 추가 * Feat: view model 연결 * Feat: view model 추가 * Feat: view model 연결 * Fix: 패키지 명 다른 오류 수정 * Remove: 미사용 resource 삭제 * Rename: 디렉토리 명 변경 (Screen >> screen) * Feat: import 문 정리 * Rename: 패키지 명 변경 적용 * Rename: 패키지 명 변경 적용 * Design: padding 조절 * Fix: Response Dto 변경 * Feat: 환불 내역 조회 response 모델 추가 * Feat: response 변경에 따른 createAt 정보 추가 * Feat: navigation 이벤트 추가 * Feat: navigation 이벤트 추가 * Feat: order status 취소 완료 상태 추가 * Feat: order status 반품 완료 상태 추가 * Fix: UI 배송비 누락 수정 * Fix: UI 배송비 누락 수정 * Feat: 반품 완료 상태 추가 * Fix: 배송비 UI 누락 수정 * Design: UI 정렬 * Design: 버튼 삭제 * Remove: 미사용 화면 삭제 * Feat: NoDataPage >> EmptyDataPage 변경 * Design: font 적용 * Remove: 미사용 import 문 제거 * Rename: 파라미터 명 변경 * Feat: 반품 진행 중 상태 추가 * Feat: order status를 기준으로 Button UI 분기 * Feat: 반품 진행 중 상태 추가 * Feat: 리뷰 작성 navigation 이벤트 추가 * Comment: 임의 이벤트 주석 추가 * Rename: 파일 위치 이동 (like 모듈 >> userInfo 모듈) * Rename: navigation 이벤트 명 변경 * Feat: 좋아요 한 향수 화면 route 추가 * Feat: navigation 이벤트 추가 * Remove: like 모듈 삭제 및 user info 모듈 병합 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Ignore: git pull * Test: sort 로직 test * Feat: Paging 내 sort 추가 * Remove: 미사용 resource 삭제 * Fix: 카테고리 내용 변경 (시향기 >> 향BTI 시향기) * Refactor: 변수 위치 변경 * Revert * Ignore: git pull * Ignore: git pull * Feat: 리뷰 컴포넌트 추가 * Feat: 선택 시 사진 확대 추가 * Feat: 선택 시 사진 확대 추가 * Design: 색상 반전 여부 추가 * Feat: int RequestBody형으로 변환 함수 추가 * Chore: decode string 함수 의존성 추가 * Feat: 리뷰 관련 dto 추가 * Feat: photo dto 추가 * Feat: h shop review 관련 api 추가 * Feat: h shop review 관련 api 추가 * Feat: 좋아요 개수 파라미터 추가 * Design: 반전 여부 추가 * Feat: review 화면 추가 * Feat: path 변환 함수 (local uri >> absolute path) * Feat: get my orders api 추가 * Feat: get my orders dto 추가 * Feat: 리뷰 작성 view model 추가 * Feat: 리뷰 작성 화면 view model 연결 * Chore: json decode import 추가 * Feat: 리뷰 작성 navigation 추가 * Fix: FAB 버튼 파라미터 변경 (고정 값 >> 변동 값) * Rename: my orders api 위치 변경 (HShop >> HShopReview) * Feat: 파라미터 타입 변경 (() -> Unit >> Unit) * Feat: navigation 이벤트 추가 * Chore: paging 의존성 추가 * Fix: val >> var * Feat: 선택 가능 여부 설정 파라미터 추가 * Feat: paging 클래스 추가 * Feat: 리뷰 화면 view model 추가 * Feat: 리뷰 화면 view model 연결 * Feat: HBTI 홈 view model 추가 * Design: 테두리 색상 남는 UI 수정 * Design: navigation icon 색상 값 추가 * Style: 코드 스타일 변경 * Feat: navigation 이벤트 추가 * Design: 디자인 파라미터 변경 * Design: 글 색 변경 * Feat: 리뷰 UI 추가 * Design: FAB 디자인 변경 * Design: FAB padding 변경 * Design: icon 색상 변경 * Design: FAB 디자인 변경 * Design: text 변경 * Design: TopBar 색상 변경 * Design: FAB 선택 시 배경 애니메이션 추가 * Design: 컴포넌트 색상 명시 * Feat: 성능 개선을 위한 분리 * Fix: public >> private * Feat: 신고, 삭제 이름 선언 * Feat: 삭제, 신고 이벤트 추가 * Fix: ui 성능 개선 * Remove: 불필요 변수 제거 * Remove: 불필요 변수 제거 * Fix: var >> val * Fix: 좋아요 로직 변경 * Feat: navigation 이벤트 추가 * Chore: material 의존성 추가 * Feat: 좋아요 이벤트 추가 * Feat: 좋아요, 삭제, 신고 기능 추가 * Feat: 수정 api 추가 * Feat: 리뷰 수정 화면 추가 * Feat: 리뷰 수정 비즈니스 로직 추가 * Feat: 리뷰 수정 화면 네비게이션 연결 * Ignore * Design: FAB 버튼 테두리 삭제 * Fix: navigation 이벤트 호출 수정 * Feat: 리뷰 단건 조회, 삭제 api 추가 * Feat: FAB option 변수 값 변경 * Feat: delete review 함수 연결 * Fix: part 어노테이션 네이밍 오류 수정 * Fix: 함수 파라미터 변경 * Fix: 함수 파라미터 변경 * Feat: 삭제 후 ui 반영되도록 flag 추가 * Fix: delay 시간 축소 * Remove: log 삭제 * Design: 아이콘 변경 * Design: 스크롤 범위 전체로 변경 * Feat: 개별 navigation 람다 적용 * Feat: 개별 navigation 람다 적용 * Fix: Part 어노테이션 이름 추가 * Feat: 리뷰 수정 화면 navigation 연결 * Feat: single top 옵션 추가 * Design: 배경 이미지 추가 * Feat: 신고 기능 추가 * Feat: 리뷰 신고 api 추가 * Fix: 파라미터 명 변경 * Style: 코드 줄 변경 * Feat: 이벤트 후 dialog 닫기 * Feat: 작성한 리뷰 navigation 연결 * Rename: getMyOrders api 위치 이동 (hShopReview >> HShop) * Feat: 내가 작성한 review api 추가 * Feat: 내가 작성한 review 화면 추가 * Feat: 내가 작성한 review view model 추가 * Feat: 내 review paging source * Feat: 내 review 화면 연결 * Rename: paging source 위치 이동 * Feat: 리뷰 완료 상태 추가 * Feat: navigation 이벤트 추가 * Feat: createdAt 멤버 변수 추가 * Design: 클릭 범위 변경 * Design: 클릭 범위 변경 * Feat: navigation 파라미터 추가 * Feat: 환불 버튼 클릭 시 dialog 생성 * Design: fontSize, lineHeight 조정 * Design: 날짜 추가, 색상 변경 * Remove: 미사용 dto 삭제 * Fix: OrderStatus에 리뷰 완료 상태 >> isReviewed 멤버 변수로 변경 * Design: review 작성 여부와 order status에 따른 UI 변경 * Design: review 작성 여부와 order status에 따른 UI 변경 * Feat: navigation 이벤트 추가 * Design: 텍스트 문구 변경 * Fix: navigation 경로 수정 * Fix: review 사용 조건 변경 * Design: top bar 배경 색상 변경 * Refactor: 중복 함수 제거 * Fix: 닉네임 중복 확인 api 변경 반영 * Remove: 불필요 파라미터 제거 * Refactor: Recomposition 줄도록 수정 * Fix: 느린 상태 update 수정 * Fix: 느린 상태 update 수정 * Refactor: recomposition 감소 유도 * Ignore: Merge * Design: top bar 색상 추가 * Fix: 배송 요청을 선택 사항으로 변경 * Design: 단일 매거진 Pager로 변경 * Feat: ResultResponse Wrapping * Feat: nav login 네비게이션 이벤트 추가 * Refactor: Recomposition 감소 * Refactor: Recomposition 감소 * Feat: authenticator 추가 * Feat: authenticator 추가 * Style: 여백 삭제 * Design: 테두리 추가 * Refactor: Recomposition 감소 * Rename: 파라미터 명 변경 * Refactor: Recomposition 감소 * Refactor: Recomposition 감소 * Fix: NullPointerException 오류 수정 * Design: 버튼 색상 변경 * Design: 뒤고 가기 버튼 삭제 * Feat: navigation 도착지 변경 (홈 >> Hbti 홈) * Feat: navigation stack 정리 * Feat: navigation stack 정리 * Fix: Nickname Input 컴포넌트 파라미터 변경에 따른 수정 --- .../java/com/hmoa/app/navigation/NavHost.kt | 86 ++++++++++-- .../Bootpay/BootpayDataStoreImpl.kt | 30 +++- .../core_datastore/Member/MemberDataStore.kt | 4 +- .../Member/MemberDataStoreImpl.kt | 79 +++++++++-- .../component/AppDesignDialog.kt | 24 +++- .../component/NicknameInput.kt | 6 +- .../repository/MemberRepository.kt | 4 +- .../core_network/service/MemberService.kt | 4 +- .../core_repository/MemberRepositoryImpl.kt | 4 +- .../PickNicknameScreen.kt | 129 ++++++++++-------- .../viewmodel/PickNicknameViewmodel.kt | 45 ++++-- .../com/hmoa/feature_fcm/AlarmViewModel.kt | 16 ++- .../feature_hbti/navigation/HbtiNavigation.kt | 25 ++-- .../feature_hbti/screen/OrderResultScreen.kt | 25 +--- .../feature_userinfo/Screen/MyBirthPage.kt | 127 +++++++++-------- .../feature_userinfo/Screen/MyCommentPage.kt | 27 ++-- .../Screen/MyFavoriteCommentPage.kt | 69 +++++----- .../Screen/MyFavoritePrefumePage.kt | 125 +++++++++-------- .../feature_userinfo/Screen/MyGenderPage.kt | 57 ++++---- .../hmoa/feature_userinfo/Screen/MyPage.kt | 28 +++- .../feature_userinfo/Screen/RefundPage.kt | 52 ++++--- .../feature_userinfo/navigation/NavGraph.kt | 13 +- .../viewModel/FavoriteCommentViewModel.kt | 23 ++-- .../viewModel/MyBirthViewModel.kt | 55 ++++---- .../viewModel/MyFavoritePerfumeViewModel.kt | 53 ++----- .../viewModel/MyGenderViewModel.kt | 55 ++++---- 26 files changed, 676 insertions(+), 489 deletions(-) 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 127470201..0a8948e27 100644 --- a/app/src/main/java/com/hmoa/app/navigation/NavHost.kt +++ b/app/src/main/java/com/hmoa/app/navigation/NavHost.kt @@ -3,14 +3,61 @@ package com.hmoa.app.navigation import androidx.compose.runtime.Composable import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost -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_hbti.navigation.* -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 @@ -18,8 +65,30 @@ import com.hmoa.feature_hpedia.Navigation.nestedHPediaGraph 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_userinfo.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( @@ -217,10 +286,7 @@ fun SetUpNavGraph( navOrder = navController::navigateToOrder, navLogin = navController::navigateToLogin ) - orderResult( - navBack = navController::navigateToBack, - navHome = navController::navigateToHome - ) + orderResult(navHbti = navController::navigateToHbti) perfumeRecommendationRoute( onBackClick = navController::navigateToBack, onNextClick = navController::navigateToPerfumeRecommendationResult 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 index 33a5b78e5..e9d0370a4 100644 --- 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 @@ -1,27 +1,33 @@ package com.hmoa.core_datastore.Bootpay import ResultResponse -import com.hmoa.core_model.data.ErrorMessage 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 kotlinx.serialization.json.Json import javax.inject.Inject class BootpayDataStoreImpl @Inject constructor( - private val bootpayService: BootpayService + 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{ - result.errorMessage = Json.decodeFromString(this.message()) + authenticator.handleApiError( + rawMessage = this.message(), + handleErrorMesssage = { result.errorMessage = it }, + onCompleteTokenRefresh = { + bootpayService.postConfirm(requestDto).suspendOnSuccess { result.data = this.data } + } + ) } return result } @@ -31,7 +37,13 @@ class BootpayDataStoreImpl @Inject constructor( bootpayService.postCancel(requestDto).suspendOnSuccess{ result.data = this.data }.suspendOnError{ - result.errorMessage = Json.decodeFromString(this.message()) + authenticator.handleApiError( + rawMessage = this.message(), + handleErrorMesssage = { result.errorMessage = it }, + onCompleteTokenRefresh = { + bootpayService.postCancel(requestDto).suspendOnSuccess { result.data = this.data } + } + ) } return result } @@ -41,7 +53,13 @@ class BootpayDataStoreImpl @Inject constructor( bootpayService.deleteOrder(orderId).suspendOnSuccess{ result.data = this.data }.suspendOnError{ - result.errorMessage = Json.decodeFromString(this.message()) + authenticator.handleApiError( + rawMessage = this.message(), + handleErrorMesssage = { result.errorMessage = it }, + onCompleteTokenRefresh = { + bootpayService.deleteOrder(orderId).suspendOnSuccess { result.data = this.data } + } + ) } return result } 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 9cdbf58c1..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 @@ -20,7 +20,7 @@ interface MemberDataStore { suspend fun getMember(): ResultResponse suspend fun getAddress(): ResultResponse suspend fun postAddress(request: DefaultAddressDto): ResultResponse> - suspend fun updateAge(request: AgeRequestDto): DataResponseDto + suspend fun updateAge(request: AgeRequestDto): ResultResponse> suspend fun getCommunities(page: Int): ResultResponse> suspend fun getCommunityComments(page: Int): ResultResponse> suspend fun getCommunityFavoriteComments(page: Int): ResultResponse> @@ -36,5 +36,5 @@ interface MemberDataStore { 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 3e4e95303..9d8180061 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 @@ -14,9 +14,9 @@ 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_network.authentication.Authenticator 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 @@ -63,14 +63,31 @@ class MemberDataStoreImpl @Inject constructor( memberService.postAddress(request).suspendOnSuccess{ result.data = this.data }.suspendOnError{ - val errorMessage = Json.decodeFromString(this.message()) - result.errorMessage = errorMessage + 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> { @@ -167,8 +184,13 @@ class MemberDataStoreImpl @Inject constructor( memberService.getOrder(cursor).suspendOnSuccess{ result.data = this.data }.suspendOnError{ - val errorMessage = Json.decodeFromString(this.message()) - result.errorMessage = errorMessage + authenticator.handleApiError( + rawMessage = this.message(), + handleErrorMesssage = { result.errorMessage = it }, + onCompleteTokenRefresh = { + memberService.getOrder(cursor).suspendOnSuccess { result.data = this.data } + } + ) } return result } @@ -178,8 +200,13 @@ class MemberDataStoreImpl @Inject constructor( memberService.getRefundRecord(cursor).suspendOnSuccess{ result.data = this.data }.suspendOnError{ - val errorMessage = Json.decodeFromString(this.message()) - result.errorMessage = errorMessage + authenticator.handleApiError( + rawMessage = this.message(), + handleErrorMesssage = { result.errorMessage = it }, + onCompleteTokenRefresh = { + memberService.getRefundRecord(cursor).suspendOnSuccess { result.data = this.data } + } + ) } return result } @@ -189,8 +216,13 @@ class MemberDataStoreImpl @Inject constructor( memberService.getOrderInfo().suspendOnSuccess{ result.data = this.data }.suspendOnError{ - val errorMessage = Json.decodeFromString(this.message()) - result.errorMessage = errorMessage + authenticator.handleApiError( + rawMessage = this.message(), + handleErrorMesssage = { result.errorMessage = it }, + onCompleteTokenRefresh = { + memberService.getOrderInfo().suspendOnSuccess { result.data = this.data } + } + ) } return result } @@ -200,8 +232,13 @@ class MemberDataStoreImpl @Inject constructor( memberService.postOrderInfo(request).suspendOnSuccess{ result.data = this.data }.suspendOnError{ - val errorMessage = Json.decodeFromString(this.message()) - result.errorMessage = errorMessage + authenticator.handleApiError( + rawMessage = this.message(), + handleErrorMesssage = { result.errorMessage = it }, + onCompleteTokenRefresh = { + memberService.postOrderInfo(request).suspendOnSuccess { result.data = this.data } + } + ) } return result } @@ -279,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-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/NicknameInput.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/NicknameInput.kt index 5e2bacbc3..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 @@ -49,7 +49,7 @@ fun NicknameInput( LaunchedEffect(isAvailable) { descriptionText = handleText(isAvailable) - descriptionTextColor = handleTextColor(isAvailable ?: false, initNickname, nickname) + descriptionTextColor = handleTextColor(isAvailable) } LaunchedEffect(nickname){ if(initNickname != nickname) clearAvailable() } @@ -155,8 +155,8 @@ fun isLengthUnder9(text: String): Boolean { return false } -fun handleTextColor(isAvailable: Boolean, initNickname: String?, currentNickname: String): Color { - return if(initNickname != currentNickname){ +fun handleTextColor(isAvailable: Boolean?): Color { + return if(isAvailable == null){ Color.Black } else { if (isAvailable) { 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 f2730df69..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 @@ -20,7 +20,7 @@ interface MemberRepository { suspend fun getMember(): ResultResponse suspend fun getAddress(): ResultResponse suspend fun postAddress(request: DefaultAddressDto): ResultResponse> - suspend fun updateAge(request: AgeRequestDto): DataResponseDto + suspend fun updateAge(request: AgeRequestDto): ResultResponse> suspend fun getCommunities(page: Int): ResultResponse> suspend fun getCommunityComments(page: Int): ResultResponse> suspend fun getCommunityFavoriteComments(page: Int): ResultResponse> @@ -36,5 +36,5 @@ interface MemberRepository { 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-network/src/main/java/com/hmoa/core_network/service/MemberService.kt b/core-network/src/main/java/com/hmoa/core_network/service/MemberService.kt index 97ef73d25..6c8b0fae1 100644 --- a/core-network/src/main/java/com/hmoa/core_network/service/MemberService.kt +++ b/core-network/src/main/java/com/hmoa/core_network/service/MemberService.kt @@ -32,7 +32,7 @@ interface MemberService { @POST("/member/address") suspend fun postAddress(@Body request: DefaultAddressDto): ApiResponse> @PATCH("/member/age") - suspend fun updateAge(@Body request: AgeRequestDto): DataResponseDto + suspend fun updateAge(@Body request: AgeRequestDto): ApiResponse> @GET("/member/communities") suspend fun getCommunities(@Query("page") page: Int): ApiResponse> @GET("/member/communityComments") @@ -69,5 +69,5 @@ interface MemberService { @DELETE("/member/profile-photo") suspend fun deleteProfilePhoto(): DataResponseDto @PATCH("/member/sex") - suspend fun updateSex(@Body request: SexRequestDto): DataResponseDto + suspend fun updateSex(@Body request: SexRequestDto): ApiResponse> } \ No newline at end of file diff --git a/core-repository/src/main/java/com/hmoa/core_repository/MemberRepositoryImpl.kt b/core-repository/src/main/java/com/hmoa/core_repository/MemberRepositoryImpl.kt index 954113db7..8b3d61836 100644 --- a/core-repository/src/main/java/com/hmoa/core_repository/MemberRepositoryImpl.kt +++ b/core-repository/src/main/java/com/hmoa/core_repository/MemberRepositoryImpl.kt @@ -34,7 +34,7 @@ class MemberRepositoryImpl @Inject constructor( return memberDataStore.postAddress(request) } - override suspend fun updateAge(request: AgeRequestDto): DataResponseDto { + override suspend fun updateAge(request: AgeRequestDto): ResultResponse> { return memberDataStore.updateAge(request) } @@ -98,7 +98,7 @@ class MemberRepositoryImpl @Inject constructor( return memberDataStore.deleteProfilePhoto() } - override suspend fun updateSex(request: SexRequestDto): DataResponseDto { + override suspend fun updateSex(request: SexRequestDto): ResultResponse> { return memberDataStore.updateSex(request) } } \ No newline at end of file diff --git a/feature-authentication/src/main/java/com/hmoa/feature_authentication/PickNicknameScreen.kt b/feature-authentication/src/main/java/com/hmoa/feature_authentication/PickNicknameScreen.kt index 635aa6584..052560747 100644 --- a/feature-authentication/src/main/java/com/hmoa/feature_authentication/PickNicknameScreen.kt +++ b/feature-authentication/src/main/java/com/hmoa/feature_authentication/PickNicknameScreen.kt @@ -1,8 +1,18 @@ package com.hmoa.feature_authentication -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable +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.res.painterResource @@ -14,15 +24,13 @@ import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.hmoa.core_designsystem.R -import com.hmoa.core_designsystem.component.TopBar import com.hmoa.core_designsystem.component.Button import com.hmoa.core_designsystem.component.NicknameInput +import com.hmoa.core_designsystem.component.TopBar import com.hmoa.core_designsystem.theme.CustomColor import com.hmoa.feature_authentication.viewmodel.PickNicknameUiState import com.hmoa.feature_authentication.viewmodel.PickNicknameViewmodel -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch +import kotlinx.coroutines.flow.MutableSharedFlow @Composable @@ -31,19 +39,13 @@ internal fun PickNicknameRoute( onSignupClick: () -> Unit, viewmodel: PickNicknameViewmodel = hiltViewModel() ) { - val scope = CoroutineScope(Dispatchers.IO) - val isAvailableState by viewmodel.isExistedNicknameState.collectAsStateWithLifecycle() - + val uiState by viewmodel.uiState.collectAsStateWithLifecycle() PickNicknameScreen( onPickPersonalInfoClick, onSignupClick, - isExistedNicknameState = isAvailableState, - onCheckNicknameDuplication = { - scope.launch { - viewmodel.onNicknameChanged(it) - viewmodel.saveNickname(it) - } - } + uiState = uiState, + onCheckNicknameDuplication = viewmodel::onNicknameChanged, + onSaveNickname = viewmodel::saveNickname ) } @@ -51,56 +53,69 @@ internal fun PickNicknameRoute( fun PickNicknameScreen( onPickPersonalInfoClick: () -> Unit, onSignupClick: () -> Unit, - isExistedNicknameState: PickNicknameUiState = PickNicknameUiState.PickNickname(isExistedNickname = true), - onCheckNicknameDuplication: (nickname: String) -> Unit + uiState: PickNicknameUiState, + onCheckNicknameDuplication: (nickname: String) -> Unit, + onSaveNickname: (nickname: String) -> Unit, ) { - var isAvailableNickname by remember { mutableStateOf(false) } - - LaunchedEffect(isExistedNicknameState) { - isAvailableNickname = handleNicknameInput(isExistedNicknameState) - } - - Column( - horizontalAlignment = Alignment.Start, - verticalArrangement = Arrangement.SpaceBetween, - modifier = Modifier.fillMaxHeight().fillMaxWidth() - ) { - Column { - TopBar( - navIcon = painterResource(R.drawable.ic_back), - onNavClick = { onSignupClick() }, - title = "1/2" - ) - Column() { - Text( - "닉네임", - modifier = Modifier.padding(top = 60.dp).padding(horizontal = 15.dp), - style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Thin, color = CustomColor.gray4) - ) - NicknameInput( - onPressNicknameExist = { onCheckNicknameDuplication(it) }, - isAvailable = isAvailableNickname + when(uiState){ + PickNicknameUiState.Loading -> {} + PickNicknameUiState.Empty -> {} + is PickNicknameUiState.PickNickname -> { + val isAvailableNickname by uiState.isExistedNickname.collectAsStateWithLifecycle(initialValue = null) + var nickname by remember{mutableStateOf(uiState.initNickname)} + val isEnabled by remember{derivedStateOf{isAvailableNickname!=null && isAvailableNickname!! && nickname == uiState.initNickname}} + Column( + horizontalAlignment = Alignment.Start, + verticalArrangement = Arrangement.SpaceBetween, + modifier = Modifier + .fillMaxHeight() + .fillMaxWidth() + ) { + Column { + TopBar( + navIcon = painterResource(R.drawable.ic_back), + onNavClick = { onSignupClick() }, + title = "1/2" + ) + Column() { + Text( + "닉네임", + modifier = Modifier + .padding(top = 60.dp) + .padding(horizontal = 15.dp), + style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Thin, color = CustomColor.gray4) + ) + NicknameInput( + initNickname = nickname, + onPressNicknameExist = { + onCheckNicknameDuplication(it) + nickname = it + }, + isAvailable = isAvailableNickname + ) + } + } + Button( + isEnabled, + "다음", + { + onSaveNickname(nickname) + onPickPersonalInfoClick() + }, + Modifier + .fillMaxWidth() + .height(80.dp), ) } + } - Button( - isAvailableNickname, - "다음", - { onPickPersonalInfoClick() }, - Modifier.fillMaxWidth().height(80.dp), - ) } -} -fun handleNicknameInput(value: PickNicknameUiState): Boolean { - if (value == PickNicknameUiState.PickNickname(isExistedNickname = true)) { - return false - } - return true + } @Preview @Composable fun PickNicknameScreenPreview() { - PickNicknameScreen({}, {}, PickNicknameUiState.PickNickname(isExistedNickname = true), {}) + PickNicknameScreen({}, {}, PickNicknameUiState.PickNickname("", MutableSharedFlow()), {}, {}) } \ No newline at end of file diff --git a/feature-authentication/src/main/java/com/hmoa/feature_authentication/viewmodel/PickNicknameViewmodel.kt b/feature-authentication/src/main/java/com/hmoa/feature_authentication/viewmodel/PickNicknameViewmodel.kt index f5fb610b2..b79ec0e58 100644 --- a/feature-authentication/src/main/java/com/hmoa/feature_authentication/viewmodel/PickNicknameViewmodel.kt +++ b/feature-authentication/src/main/java/com/hmoa/feature_authentication/viewmodel/PickNicknameViewmodel.kt @@ -1,13 +1,17 @@ package com.hmoa.feature_authentication.viewmodel import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import com.hmoa.core_domain.repository.MemberRepository import com.hmoa.core_domain.repository.SignupRepository import com.hmoa.core_model.request.NickNameRequestDto import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.update +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel @@ -16,24 +20,37 @@ class PickNicknameViewmodel @Inject constructor( private val signupRepository: SignupRepository, ) : ViewModel() { - private val _isExistedNicknameState = MutableStateFlow(PickNicknameUiState.PickNickname(isExistedNickname = true)) - val isExistedNicknameState = _isExistedNicknameState.asStateFlow() - - suspend fun saveNickname(nickname: String) { - signupRepository.saveNickname(nickname) + val uiState: StateFlow = flow{ + emit(PickNicknameUiState.PickNickname("", MutableSharedFlow(1))) + }.stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(3_000), + initialValue = PickNicknameUiState.Loading + ) + fun saveNickname(nickname: String) { + viewModelScope.launch{signupRepository.saveNickname(nickname)} } - - suspend fun onNicknameChanged(nickname: String?) { - val result = memberRepository.postExistsNickname(NickNameRequestDto(nickname)).data!! - _isExistedNicknameState.update { PickNicknameUiState.PickNickname(result) } + fun onNicknameChanged(nickname: String) { + viewModelScope.launch{ + val result = memberRepository.postExistsNickname(NickNameRequestDto(nickname)).data!! + if(uiState.value is PickNicknameUiState.PickNickname) { + (uiState.value as PickNicknameUiState.PickNickname).updateIsExisted(nickname, !result) + } + } } } sealed interface PickNicknameUiState { data object Loading : PickNicknameUiState data class PickNickname( - val isExistedNickname: Boolean - ) : PickNicknameUiState + var initNickname: String, + val isExistedNickname: MutableSharedFlow + ) : PickNicknameUiState { + fun updateIsExisted(nickname: String, isExisted: Boolean?){ + this.isExistedNickname.tryEmit(isExisted) + this.initNickname = nickname + } + } data object Empty : PickNicknameUiState } \ No newline at end of file diff --git a/feature-fcm/src/main/java/com/hmoa/feature_fcm/AlarmViewModel.kt b/feature-fcm/src/main/java/com/hmoa/feature_fcm/AlarmViewModel.kt index 93ad6999e..f89935508 100644 --- a/feature-fcm/src/main/java/com/hmoa/feature_fcm/AlarmViewModel.kt +++ b/feature-fcm/src/main/java/com/hmoa/feature_fcm/AlarmViewModel.kt @@ -5,6 +5,8 @@ import androidx.lifecycle.viewModelScope import com.hmoa.core_common.ErrorUiState import com.hmoa.core_common.Result import com.hmoa.core_common.asResult +import com.hmoa.core_common.emitOrThrow +import com.hmoa.core_common.handleErrorType import com.hmoa.core_domain.repository.FcmRepository import com.hmoa.core_model.data.ErrorMessage import com.hmoa.core_model.response.AlarmResponse @@ -24,7 +26,6 @@ import javax.inject.Inject class AlarmViewModel @Inject constructor( private val fcmRepository: FcmRepository ) : ViewModel() { - private var expiredTokenErrorState = MutableStateFlow(false) private var wrongTypeTokenErrorState = MutableStateFlow(false) private var unLoginedErrorState = MutableStateFlow(false) @@ -48,13 +49,17 @@ class AlarmViewModel @Inject constructor( ) val uiState : StateFlow = flow{ - val result = fcmRepository.getFcmList() - if (result.errorMessage is ErrorMessage) throw Exception(result.errorMessage!!.message) - emit(result) + fcmRepository.getFcmList().emitOrThrow{emit(it)} }.asResult().map{ result -> when(result){ is Result.Error -> { - generalErrorState.update{Pair(true, result.exception.message)} + handleErrorType( + error = result.exception, + onExpiredTokenError = {expiredTokenErrorState.update{true}}, + onWrongTypeTokenError = {wrongTypeTokenErrorState.update{true}}, + onUnknownError = {unLoginedErrorState.update{true}}, + onGeneralError = {generalErrorState.update{Pair(true, result.exception.message)}}, + ) AlarmUiState.Error } Result.Loading -> AlarmUiState.Loading @@ -76,7 +81,6 @@ class AlarmViewModel @Inject constructor( (uiState.value as AlarmUiState.Success).checkAlarm(id) } } - } sealed interface AlarmUiState{ diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/navigation/HbtiNavigation.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/navigation/HbtiNavigation.kt index 8e638c460..e8e0b3807 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/navigation/HbtiNavigation.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/navigation/HbtiNavigation.kt @@ -6,14 +6,17 @@ import androidx.navigation.NavType import androidx.navigation.compose.composable import androidx.navigation.navArgument import com.google.gson.GsonBuilder -import com.hmoa.core_domain.entity.data.NoteOrderQuantity import com.hmoa.core_domain.entity.navigation.HbtiRoute +import com.hmoa.core_domain.entity.navigation.HomeRoute import com.hmoa.core_model.data.NoteProductIds import com.hmoa.feature_hbti.screen.* import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json -fun NavController.navigateToHbti() = navigate("${HbtiRoute.Hbti}") { launchSingleTop = true } +fun NavController.navigateToHbti() = navigate("${HbtiRoute.Hbti}") { + popUpTo(HomeRoute.Home.name){inclusive = false} + launchSingleTop = true +} fun NavController.navigateToHbtiSurvey() = navigate("${HbtiRoute.HbtiSurvey}") { launchSingleTop = true } fun NavController.navigateToHbtiSurveyResult() = navigate("${HbtiRoute.HbtiSurveyResult}") { launchSingleTop = true } @@ -21,7 +24,7 @@ fun NavController.navigateToHbtiSurveyResult() = fun NavController.navigateToHbtiSurveyLoading() = navigate("${HbtiRoute.HbtiSurveyLoading}") -fun NavController.navigateToHbtiProcess() = navigate("${com.hmoa.core_domain.entity.navigation.HbtiRoute.HbtiProcess}") +fun NavController.navigateToHbtiProcess() = navigate("${HbtiRoute.HbtiProcess}") fun NavController.navigateToNotePick() = navigate("${HbtiRoute.NotePick}") @@ -234,17 +237,9 @@ fun NavGraphBuilder.addAddress( } } -fun NavGraphBuilder.orderResult( - navBack: () -> Unit, - navHome: () -> Unit -){ - composable( - route = HbtiRoute.OrderResultRoute.name - ){ - OrderResultRoute( - navBack = navBack, - navHome = navHome - ) +fun NavGraphBuilder.orderResult(navHbti: () -> Unit){ + composable(route = HbtiRoute.OrderResultRoute.name){ + OrderResultRoute(navHbti = navHbti) } } @@ -297,4 +292,4 @@ fun NavGraphBuilder.editReview(navReview: (befRoute: HbtiRoute) -> Unit, navLogi navLogin = navLogin ) } -} \ No newline at end of file +} diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/OrderResultScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/OrderResultScreen.kt index 1a896308f..48f3beace 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/OrderResultScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/OrderResultScreen.kt @@ -18,23 +18,19 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import com.hmoa.core_designsystem.component.TopBar import com.hmoa.core_designsystem.component.Button +import com.hmoa.core_designsystem.component.TopBar import com.hmoa.core_designsystem.theme.CustomFont @Composable fun OrderResultRoute( - navBack: () -> Unit, - navHome: () -> Unit + navHbti: () -> Unit ){ - OrderResultScreen(navBack, navHome) + OrderResultScreen(navHbti) } @Composable -fun OrderResultScreen( - navBack: () -> Unit, - navHome: () -> Unit, -){ +fun OrderResultScreen(navHbti: () -> Unit){ Column( modifier = Modifier .fillMaxSize() @@ -43,11 +39,7 @@ fun OrderResultScreen( .padding(horizontal = 16.dp), horizontalAlignment = Alignment.CenterHorizontally ){ - TopBar( - title = "결제완료", - navIcon = painterResource(com.hmoa.core_designsystem.R.drawable.ic_back), - onNavClick = navBack - ) + TopBar(title = "결제완료") Spacer(Modifier.weight(1f)) Image( modifier = Modifier.size(110.dp), @@ -66,7 +58,7 @@ fun OrderResultScreen( radious = 5, isEnabled = true, btnText = "홈으로 돌아가기", - onClick = navHome + onClick = navHbti ) } } @@ -74,8 +66,5 @@ fun OrderResultScreen( @Preview @Composable private fun OrderResultUITest(){ - OrderResultScreen( - navBack = {}, - navHome = {} - ) + OrderResultScreen(navHbti = {}) } \ No newline at end of file diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyBirthPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyBirthPage.kt index 55a898d3c..cea2cef61 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyBirthPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyBirthPage.kt @@ -1,25 +1,42 @@ package com.hmoa.feature_userinfo.screen import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Column +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.material.ExperimentalMaterialApi import androidx.compose.material.ModalBottomSheetLayout import androidx.compose.material.ModalBottomSheetValue import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.hmoa.core_common.ErrorUiState import com.hmoa.core_designsystem.R -import com.hmoa.core_designsystem.component.* +import com.hmoa.core_designsystem.component.AppLoadingScreen +import com.hmoa.core_designsystem.component.Button +import com.hmoa.core_designsystem.component.ErrorUiSetView +import com.hmoa.core_designsystem.component.Spinner +import com.hmoa.core_designsystem.component.TopBar +import com.hmoa.core_designsystem.component.YearPickerDialog import com.hmoa.core_designsystem.theme.CustomColor import com.hmoa.feature_userinfo.viewModel.MyBirthUiState import com.hmoa.feature_userinfo.viewModel.MyBirthViewModel @@ -29,54 +46,42 @@ import java.time.LocalDateTime @Composable fun MyBirthRoute( navBack: () -> Unit, + navLogin: () -> Unit, viewModel: MyBirthViewModel = hiltViewModel() ) { - val availableYearRange = (1950..LocalDateTime.now().year).toList() - val uiState = viewModel.uiState.collectAsStateWithLifecycle() val errorState = viewModel.errorUiState.collectAsStateWithLifecycle() - val isEnabled = viewModel.isEnabled.collectAsStateWithLifecycle(false) - val birth = viewModel.birth.collectAsStateWithLifecycle() - + val saveBirth = remember<(newBirth: Int) -> Unit>{{viewModel.saveBirth(it, navBack)}} MyBirthPage( - availableYearRange = availableYearRange, uiState = uiState.value, errorState = errorState.value, - birth = birth.value, - isEnabled = isEnabled.value, - onUpdateBirth = { viewModel.updateBirth(it) }, - onSaveBirth = { viewModel.saveBirth() }, - navBack = navBack + saveBirth = saveBirth, + navBack = navBack, + navLogin = navLogin ) } @Composable fun MyBirthPage( - availableYearRange: List, uiState: MyBirthUiState, errorState: ErrorUiState, - birth: Int?, - isEnabled: Boolean, - onUpdateBirth: (Int) -> Unit, - onSaveBirth: () -> Unit, - navBack: () -> Unit + saveBirth: (newBirth: Int) -> Unit, + navBack: () -> Unit, + navLogin: () -> Unit ) { when (uiState) { MyBirthUiState.Loading -> AppLoadingScreen() - MyBirthUiState.Success -> { + is MyBirthUiState.Success -> { SelectBirthContent( - availableYearRange = availableYearRange, - birth = birth!!, - isEnabled = isEnabled, - onUpdateBirth = onUpdateBirth, - onSaveBirth = onSaveBirth, + initBirth = uiState.defaultBirth, + saveBirth = saveBirth, navBack = navBack ) } MyBirthUiState.Error -> { ErrorUiSetView( - onLoginClick = navBack, + onLoginClick = navLogin, errorUiState = errorState, onCloseClick = navBack ) @@ -87,40 +92,44 @@ fun MyBirthPage( @OptIn(ExperimentalMaterialApi::class) @Composable private fun SelectBirthContent( - availableYearRange: List, - birth: Int, - isEnabled: Boolean, - onUpdateBirth: (Int) -> Unit, - onSaveBirth: () -> Unit, + initBirth: Int, + saveBirth: (newBirth: Int) -> Unit, navBack: () -> Unit ) { + val availableYearRange = (1950..LocalDateTime.now().year).toList() + var currentBirth by remember{mutableStateOf(initBirth)} val scope = rememberCoroutineScope() val modalSheetState = androidx.compose.material.rememberModalBottomSheetState( initialValue = ModalBottomSheetValue.Hidden, confirmValueChange = { it != ModalBottomSheetValue.HalfExpanded }, skipHalfExpanded = true ) + val isEnabled by remember{derivedStateOf{initBirth != currentBirth}} + val dialogOpen: () -> Unit = {scope.launch{modalSheetState.show()}} + val dialogClose: () -> Unit = {scope.launch{modalSheetState.hide()}} + ModalBottomSheetLayout( sheetState = modalSheetState, sheetContent = { - Column( - modifier = Modifier - .fillMaxHeight() - .background(CustomColor.gray4), - verticalArrangement = Arrangement.Bottom - ) { - YearPickerDialog( - yearList = availableYearRange, - initialValue = birth, - height = 370.dp, - onDismiss = { scope.launch { modalSheetState.hide() } }, - onDoneClick = { - onUpdateBirth(it) - scope.launch { modalSheetState.hide() } - } - ) - } - } +// Column( +// modifier = Modifier +// .fillMaxHeight() +// .background(CustomColor.gray4), +// verticalArrangement = Arrangement.Bottom +// ) { +// } + YearPickerDialog( + yearList = availableYearRange, + initialValue = initBirth, + height = 370.dp, + onDismiss = dialogClose, + onDoneClick = { + currentBirth = it + dialogClose() + } + ) + }, + sheetBackgroundColor = CustomColor.gray4 ) { Column( modifier = Modifier @@ -128,7 +137,7 @@ private fun SelectBirthContent( .background(color = Color.White) ) { TopBar( - navIcon = painterResource(com.hmoa.core_designsystem.R.drawable.ic_back), + navIcon = painterResource(R.drawable.ic_back), onNavClick = navBack, title = "출생연도" ) @@ -149,8 +158,8 @@ private fun SelectBirthContent( Spinner( width = 152.dp, height = 46.dp, - value = birth, - onClick = { scope.launch { modalSheetState.show() } }, + value = currentBirth, + onClick = dialogOpen, placeholder = "선택" ) } @@ -160,11 +169,17 @@ private fun SelectBirthContent( .height(82.dp), isEnabled = isEnabled, btnText = "변경", - onClick = { - onSaveBirth() - navBack() - } + onClick = { saveBirth(currentBirth) } ) } } +} + +@Preview +@Composable +fun BrithTest(){ + var initBirth by remember{mutableIntStateOf(0)} + SelectBirthContent( + initBirth = initBirth, saveBirth = { }, navBack = {} + ) } \ No newline at end of file diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyCommentPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyCommentPage.kt index 3d503b209..6f54b8947 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyCommentPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyCommentPage.kt @@ -1,16 +1,10 @@ package com.hmoa.feature_userinfo.screen import androidx.compose.foundation.background -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.padding -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.HorizontalDivider import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -27,12 +21,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.paging.ItemSnapshotList import androidx.paging.compose.collectAsLazyPagingItems import com.hmoa.core_common.ErrorUiState -import com.hmoa.core_designsystem.component.AppLoadingScreen -import com.hmoa.core_designsystem.component.Comment -import com.hmoa.core_designsystem.component.EmptyDataPage -import com.hmoa.core_designsystem.component.ErrorUiSetView -import com.hmoa.core_designsystem.component.TopBar -import com.hmoa.core_designsystem.component.TypeBadge +import com.hmoa.core_designsystem.component.* import com.hmoa.core_designsystem.theme.CustomColor import com.hmoa.core_domain.entity.data.MyPageCategory import com.hmoa.core_model.response.CommunityCommentDefaultResponseDto @@ -72,8 +61,6 @@ fun MyCommentPage( navLogin: () -> Unit, onTypeChanged: (type: MyPageCategory) -> Unit ) { - var isOpen by remember { mutableStateOf(true) } - when (uiState) { CommentUiState.Loading -> AppLoadingScreen() is CommentUiState.Comments -> { @@ -131,7 +118,9 @@ private fun MyCommentContent( } ) if (comments.isNotEmpty()) { - LazyColumn { + LazyColumn( + verticalArrangement = Arrangement.spacedBy(9.dp) + ) { itemsIndexed( items = comments, key = {_, contact -> contact?.id!!} @@ -148,7 +137,9 @@ private fun MyCommentContent( navCommunity = { navParent(comment.parentId) }, onOpenBottomDialog = { /** Bottom Dialog 띄울 거면 사용 */ }, isSelected = comment.liked, - onHeartClick = {} + onHeartClick = { + + } ) if (index < comments.size - 1) { HorizontalDivider(modifier = Modifier.fillMaxWidth(), thickness = 1.dp, color = CustomColor.gray2) diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyFavoriteCommentPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyFavoriteCommentPage.kt index 852c51847..92aec4fc3 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyFavoriteCommentPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyFavoriteCommentPage.kt @@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource @@ -25,42 +26,35 @@ import com.hmoa.feature_userinfo.viewModel.FavoriteCommentViewModel @Composable fun MyFavoriteCommentRoute( navBack: () -> Unit, - navCommunity: (Int) -> Unit, - navPerfume: (Int) -> Unit, + navCommunity: (communityId: Int) -> Unit, + navPerfume: (perfumeId: Int) -> Unit, viewModel: FavoriteCommentViewModel = hiltViewModel() ) { //comment list val uiState = viewModel.uiState.collectAsStateWithLifecycle() val errState = viewModel.errorUiState.collectAsStateWithLifecycle() - val type = viewModel.type.collectAsStateWithLifecycle() + val type by viewModel.type.collectAsStateWithLifecycle() MyFavoriteCommentPage( uiState = uiState.value, errState = errState.value, - commentType = type.value, - onTypeChanged = { viewModel.changeType(it) }, + commentType = type, + onTypeChanged = viewModel::changeType, navBack = navBack, - onNavParent = { - if (type.value == MyPageCategory.향수.name) { - navPerfume(it) - if (type.value == MyPageCategory.향수.name) { - navPerfume(it) - } else { - navCommunity(it) - } - } - } + navPerfume = navPerfume, + navCommunity = navCommunity, ) } @Composable fun MyFavoriteCommentPage( navBack: () -> Unit, - onNavParent: (Int) -> Unit, + navPerfume: (perfumeId: Int) -> Unit, + navCommunity: (communityId: Int) -> Unit, uiState: FavoriteCommentUiState, errState: ErrorUiState, - commentType: String, - onTypeChanged: (String) -> Unit, + commentType: MyPageCategory, + onTypeChanged: (type: MyPageCategory) -> Unit, ) { when (uiState) { FavoriteCommentUiState.Loading -> { @@ -74,7 +68,8 @@ fun MyFavoriteCommentPage( onTypeChanged = onTypeChanged, comments = comments.itemSnapshotList, navBack = navBack, - onNavParent = onNavParent + navPerfume = navPerfume, + navCommunity = navCommunity ) } @@ -85,20 +80,23 @@ fun MyFavoriteCommentPage( onCloseClick = navBack ) } - - else -> {} } } @Composable fun FavoriteCommentContent( - type: String, - onTypeChanged: (String) -> Unit, + type: MyPageCategory, + onTypeChanged: (type: MyPageCategory) -> Unit, comments: ItemSnapshotList, navBack: () -> Unit, - onNavParent: (Int) -> Unit, + navPerfume: (perfumeId: Int) -> Unit, + navCommunity: (communityId: Int) -> Unit ) { val commentCount = comments.size + val navParent: (id: Int) -> Unit = { + if (type == MyPageCategory.향수) { navPerfume(it) } + else { navCommunity(it) } + } Column( modifier = Modifier @@ -119,7 +117,10 @@ fun FavoriteCommentContent( TypeRow(type = type, onTypeChanged = onTypeChanged) if (comments.isNotEmpty()) { LazyColumn { - itemsIndexed(comments) { index, comment -> + itemsIndexed( + items = comments, + key = {_, contact -> contact?.id!!} + ) { index, comment -> if (comment != null) { Comment( isEditable = false, @@ -129,7 +130,7 @@ fun FavoriteCommentContent( comment = comment.content, isFirst = false, heartCount = comment.heartCount, - navCommunity = { onNavParent(comment.parentId) }, + navCommunity = { navParent(comment.parentId) }, onOpenBottomDialog = { /** 여기도 Bottom Dialog 사용하려면 사용합시다 */ }, isSelected = comment.liked, onHeartClick = {} @@ -154,8 +155,8 @@ fun FavoriteCommentContent( @Composable private fun TypeRow( - type: String, - onTypeChanged: (type: String) -> Unit, + type: MyPageCategory, + onTypeChanged: (type: MyPageCategory) -> Unit, ) { Row( modifier = Modifier @@ -163,21 +164,21 @@ private fun TypeRow( .wrapContentHeight(), ) { TypeBadge( - onClickItem = { onTypeChanged("향수") }, + onClickItem = { onTypeChanged(MyPageCategory.향수) }, roundedCorner = 20.dp, - type = "향수", + type = MyPageCategory.향수.name, fontSize = 12.sp, fontColor = Color.White, - selected = type == "향수" + selected = type == MyPageCategory.향수 ) Spacer(Modifier.width(8.dp)) TypeBadge( - onClickItem = { onTypeChanged("게시글") }, + onClickItem = { onTypeChanged(MyPageCategory.게시글) }, roundedCorner = 20.dp, - type = "게시글", + type = MyPageCategory.게시글.name, fontSize = 12.sp, fontColor = Color.White, - selected = type == "게시글" + selected = type == MyPageCategory.게시글 ) } } \ No newline at end of file diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyFavoritePrefumePage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyFavoritePrefumePage.kt index 2ff20f35d..8550c91cc 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyFavoritePrefumePage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyFavoritePrefumePage.kt @@ -2,7 +2,18 @@ package com.hmoa.feature_like.Screen import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background -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.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.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.itemsIndexed @@ -11,7 +22,12 @@ import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.material3.Icon import androidx.compose.material3.IconButton -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource @@ -20,7 +36,12 @@ import androidx.compose.ui.window.Dialog import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.hmoa.core_common.ErrorUiState -import com.hmoa.core_designsystem.component.* +import com.hmoa.core_designsystem.component.AppLoadingScreen +import com.hmoa.core_designsystem.component.EmptyDataPage +import com.hmoa.core_designsystem.component.ErrorUiSetView +import com.hmoa.core_designsystem.component.LikeGridItem +import com.hmoa.core_designsystem.component.LikeRowItem +import com.hmoa.core_designsystem.component.TopBar import com.hmoa.core_designsystem.theme.CustomColor import com.hmoa.core_model.response.PerfumeLikeResponseDto import com.hmoa.feature_userinfo.viewModel.MyFavoritePerfumeUiState @@ -28,27 +49,18 @@ import com.hmoa.feature_userinfo.viewModel.MyFavoritePerfumeViewModel @Composable fun MyFavoritePerfumeRoute( - navPerfume: (Int) -> Unit, + navPerfume: (perfumeId: Int) -> Unit, navHome: () -> Unit, navBack: () -> Unit, - onErrorHandleLoginAgain: () -> Unit, + navLogin: () -> Unit, viewModel: MyFavoritePerfumeViewModel = hiltViewModel() ) { - val uiState = viewModel.uiState.collectAsStateWithLifecycle() - var type by remember { mutableStateOf("ROW") } + val uiState by viewModel.uiState.collectAsStateWithLifecycle() val errorUiState by viewModel.errorUiState.collectAsStateWithLifecycle() MyFavoritePerfumeScreen( - uiState = uiState.value, - type = type, - onTypeChanged = { type = it }, + uiState = uiState, errorUiState = errorUiState, - onErrorHandleLoginAgain = { - if (viewModel.hasToken()) { - navHome() - } else { - onErrorHandleLoginAgain() - } - }, + navLogin = navLogin, navPerfume = navPerfume, navHome = navHome, navBack = navBack @@ -59,33 +71,23 @@ fun MyFavoritePerfumeRoute( fun MyFavoritePerfumeScreen( errorUiState: ErrorUiState, uiState: MyFavoritePerfumeUiState, - type: String, - onTypeChanged: (String) -> Unit, - navPerfume: (Int) -> Unit, + navPerfume: (perfumeId: Int) -> Unit, navHome: () -> Unit, navBack: () -> Unit, - onErrorHandleLoginAgain: () -> Unit + navLogin: () -> Unit ) { - when (uiState) { MyFavoritePerfumeUiState.Loading -> AppLoadingScreen() is MyFavoritePerfumeUiState.Like -> { - if (uiState.perfumes.isNotEmpty()) { - MyFavoritePerfumeContent( - type = type, - onTypeChanged = onTypeChanged, - perfumes = uiState.perfumes, - navPerfume = navPerfume, - navBack = navBack - ) - } else { - EmptyDataPage(mainText = "좋아요한 향수가 없습니다.") - } + MyFavoritePerfumeContent( + perfumes = uiState.perfumes, + navPerfume = navPerfume, + navBack = navBack + ) } - is MyFavoritePerfumeUiState.Error -> { ErrorUiSetView( - onLoginClick = { onErrorHandleLoginAgain() }, + onLoginClick = navLogin, errorUiState = errorUiState, onCloseClick = navHome ) @@ -95,36 +97,39 @@ fun MyFavoritePerfumeScreen( @Composable private fun MyFavoritePerfumeContent( - type: String, - onTypeChanged: (String) -> Unit, perfumes: List, - navPerfume: (Int) -> Unit, + navPerfume: (perfumeId: Int) -> Unit, navBack: () -> Unit ) { - Column( - modifier = Modifier - .fillMaxSize() - .background(color = Color.White), - ) { - TopBar( - navIcon = painterResource(com.hmoa.core_designsystem.R.drawable.ic_back), - title = "저장", - onNavClick = navBack - ) - Spacer(Modifier.height(16.dp)) - IconRow(type = type, onTypeChanged = onTypeChanged) - Spacer(Modifier.height(20.dp)) - if (type == "ROW") { - LikePerfumeListByRow( - perfumes = perfumes, - navPerfume = navPerfume - ) - } else if (type == "GRID") { - LikePerfumeListByGrid( - perfumes = perfumes, - navPerfume = navPerfume + var type by remember { mutableStateOf("ROW") } + if (perfumes.isNotEmpty()){ + Column( + modifier = Modifier + .fillMaxSize() + .background(color = Color.White), + ) { + TopBar( + navIcon = painterResource(com.hmoa.core_designsystem.R.drawable.ic_back), + title = "저장", + onNavClick = navBack ) + Spacer(Modifier.height(16.dp)) + IconRow(type = type, onTypeChanged = { type = it }) + Spacer(Modifier.height(20.dp)) + if (type == "ROW") { + LikePerfumeListByRow( + perfumes = perfumes, + navPerfume = navPerfume + ) + } else if (type == "GRID") { + LikePerfumeListByGrid( + perfumes = perfumes, + navPerfume = navPerfume + ) + } } + } else { + EmptyDataPage(mainText = "좋아요한 향수가 없습니다.") } } diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyGenderPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyGenderPage.kt index 6c3a312c8..848fba9a7 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyGenderPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyGenderPage.kt @@ -1,8 +1,19 @@ package com.hmoa.feature_userinfo.screen import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* +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.runtime.Composable +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 @@ -11,7 +22,11 @@ import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.hmoa.core_common.ErrorUiState -import com.hmoa.core_designsystem.component.* +import com.hmoa.core_designsystem.component.AppLoadingScreen +import com.hmoa.core_designsystem.component.Button +import com.hmoa.core_designsystem.component.ErrorUiSetView +import com.hmoa.core_designsystem.component.RadioButtonList +import com.hmoa.core_designsystem.component.TopBar import com.hmoa.feature_userinfo.viewModel.MyGenderUiState import com.hmoa.feature_userinfo.viewModel.MyGenderViewModel @@ -20,18 +35,14 @@ fun MyGenderRoute( navBack: () -> Unit, viewModel: MyGenderViewModel = hiltViewModel() ) { - val isEnabled = viewModel.isEnabled.collectAsStateWithLifecycle(false) - val gender = viewModel.gender.collectAsStateWithLifecycle() val uiState = viewModel.uiState.collectAsStateWithLifecycle() val errorState = viewModel.errorUiState.collectAsStateWithLifecycle() + val saveGender = remember<(gender: String)->Unit>{{ viewModel.saveGender(it, navBack)}} MyGenderPage( uiState = uiState.value, errorState = errorState.value, - gender = gender.value, - onUpdateGender = { viewModel.updateGender(it) }, - onSaveGender = { viewModel.saveGender() }, - isEnabled = isEnabled.value, + saveGender = saveGender, navBack = navBack ) } @@ -40,20 +51,15 @@ fun MyGenderRoute( fun MyGenderPage( uiState: MyGenderUiState, errorState: ErrorUiState, - gender: String?, - onUpdateGender: (String) -> Unit, - onSaveGender: () -> Unit, - isEnabled: Boolean, + saveGender: (gender: String) -> Unit, navBack: () -> Unit, ) { when (uiState) { MyGenderUiState.Loading -> AppLoadingScreen() - MyGenderUiState.Success -> { + is MyGenderUiState.Success -> { SelectGenderContent( - isEnabled = isEnabled, - gender = gender!!, - onUpdateGender = onUpdateGender, - onSaveGender = onSaveGender, + initGender = uiState.defaultGender, + saveGender = saveGender, navBack = navBack ) } @@ -70,12 +76,12 @@ fun MyGenderPage( @Composable private fun SelectGenderContent( - isEnabled: Boolean, - gender: String, - onUpdateGender: (String) -> Unit, - onSaveGender: () -> Unit, + initGender: String, + saveGender: (gender: String) -> Unit, navBack: () -> Unit ) { + var currentGender by remember{mutableStateOf(initGender)} + val isEnabled by remember{derivedStateOf{initGender != currentGender}} Column( modifier = Modifier .fillMaxSize() @@ -95,9 +101,9 @@ private fun SelectGenderContent( verticalAlignment = Alignment.CenterVertically ) { RadioButtonList( - initValue = gender, + initValue = currentGender, radioOptions = listOf("남성", "여성"), - onButtonClick = { onUpdateGender(it) } + onButtonClick = { currentGender = it } ) } Spacer(Modifier.weight(1f)) @@ -107,10 +113,7 @@ private fun SelectGenderContent( .height(78.dp), isEnabled = isEnabled, btnText = "변경", - onClick = { - onSaveGender() - navBack() - } + onClick = { saveGender(currentGender) } ) } } \ No newline at end of file diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyPage.kt index 510bac889..09a8552bd 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyPage.kt @@ -12,7 +12,15 @@ import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts 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.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.material.icons.Icons @@ -21,7 +29,12 @@ import androidx.compose.material3.HorizontalDivider 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.rememberCoroutineScope +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -40,9 +53,14 @@ import com.google.android.gms.oss.licenses.OssLicensesMenuActivity import com.hmoa.core_common.ErrorUiState import com.hmoa.core_common.checkPermission import com.hmoa.core_designsystem.R -import com.hmoa.core_designsystem.component.* +import com.hmoa.core_designsystem.component.AppLoadingScreen +import com.hmoa.core_designsystem.component.CircleImageView +import com.hmoa.core_designsystem.component.ErrorUiSetView +import com.hmoa.core_designsystem.component.OnAndOffBtn +import com.hmoa.core_designsystem.component.TopBar import com.hmoa.core_designsystem.theme.CustomColor import com.hmoa.core_domain.entity.data.ColumnData +import com.hmoa.core_domain.entity.navigation.UserInfoRoute import com.hmoa.feature_userinfo.BuildConfig import com.hmoa.feature_userinfo.screen.NoAuthMyPage import com.kakao.sdk.talk.TalkApiClient @@ -58,7 +76,7 @@ internal fun MyPageRoute( navManageMyInfo: () -> Unit, navLogin: () -> Unit, navMyPerfume: () -> Unit, - navOrderRecord: () -> Unit, + navOrderRecord: (befRoute: UserInfoRoute) -> Unit, navRefundRecord: () -> Unit, navBack: () -> Unit, viewModel: MyPageViewModel = hiltViewModel() @@ -118,7 +136,7 @@ internal fun MyPageRoute( navEditProfile = navEditProfile, navMyActivity = navMyActivity, navManageMyInfo = navManageMyInfo, - navOrderRecord = navOrderRecord, + navOrderRecord = { navOrderRecord(UserInfoRoute.MyPage) }, navRefundRecord = navRefundRecord, onErrorHandleLoginAgain = navLogin, onBackClick = navBack diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/RefundPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/RefundPage.kt index 278d4f0d4..00cb4b22b 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/RefundPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/RefundPage.kt @@ -18,7 +18,6 @@ import androidx.compose.foundation.lazy.items import androidx.compose.material3.HorizontalDivider 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 @@ -44,6 +43,7 @@ import com.hmoa.core_designsystem.component.NoteListItem import com.hmoa.core_designsystem.component.TopBar import com.hmoa.core_designsystem.theme.CustomColor import com.hmoa.core_designsystem.theme.CustomFont +import com.hmoa.core_domain.entity.navigation.UserInfoRoute import com.hmoa.core_model.response.FinalOrderResponseDto import com.hmoa.feature_userinfo.BuildConfig import com.hmoa.feature_userinfo.viewModel.RefundUiState @@ -56,23 +56,40 @@ fun RefundRoute( type: String?, orderId: Int?, navBack: () -> Unit, + navOrderRecord: (befRoute: UserInfoRoute) -> Unit, navLogin: () -> Unit, viewModel: RefundViewModel = hiltViewModel() ) { viewModel.setId(orderId) val uiState = viewModel.uiState.collectAsStateWithLifecycle() val errState = viewModel.errorUiState.collectAsStateWithLifecycle() - val isDone = viewModel.isDone.collectAsStateWithLifecycle() - ReturnOrRefundScreen( - uiState = uiState.value, - errState = errState.value, - type = type!!, - doRefund = { viewModel.refundOrder() }, - navBack = navBack, - navLogin = navLogin - ) - LaunchedEffect(isDone.value) { - if (isDone.value) navBack() + val isDone by viewModel.isDone.collectAsStateWithLifecycle() + val navOrderRecord = remember{{navOrderRecord(UserInfoRoute.RefundRoute)}} + val dialogWidth = LocalConfiguration.current.screenWidthDp.dp - 88.dp + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center + ){ + AppDesignDialog( + isOpen = isDone, + modifier = Modifier + .width(dialogWidth) + .wrapContentHeight(), + title = "환불이 완료되었습니다.", + content = "환불은 환불 규정에 따라 진행됩니다.", + onCloseClick = navOrderRecord, + onOkClick = navOrderRecord, + buttonTitle = "확인", + buttonColor = Color.Black + ) + ReturnOrRefundScreen( + uiState = uiState.value, + errState = errState.value, + type = type!!, + doRefund = { viewModel.refundOrder() }, + navBack = navBack, + navLogin = navLogin + ) } } @@ -246,16 +263,16 @@ private fun RefundContent( onClick = { if(type == "refund") showDialog = true else TalkApiClient.instance.chatChannel(context, BuildConfig.KAKAO_CHAT_PROFILE) { err -> - if (err != null) { - Toast.makeText(context, "향모아 챗봇 오류가 발생했습니다:(", Toast.LENGTH_LONG).show() - } + if (err != null) { Toast.makeText(context, "향모아 챗봇 오류가 발생했습니다:(", Toast.LENGTH_LONG).show() } } } ) } AppDesignDialog( isOpen = showDialog, - modifier = Modifier.width(dialogWidth).wrapContentHeight(), + modifier = Modifier + .width(dialogWidth) + .wrapContentHeight(), title = "환불하시겠습니까?", content = "환불은 환불 규정에 따라 진행됩니다.", onCloseClick = {showDialog = false}, @@ -263,7 +280,8 @@ private fun RefundContent( doRefund() showDialog = false }, - buttonTitle = "확인" + buttonTitle = "확인", + buttonColor = Color.Black ) } } diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/navigation/NavGraph.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/navigation/NavGraph.kt index 3c1a62325..48bef1443 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/navigation/NavGraph.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/navigation/NavGraph.kt @@ -62,7 +62,9 @@ fun NavController.navigateToRefund(type: String, orderId: Int) = navigate("${UserInfoRoute.RefundRoute.name}/${type}/${orderId}") //주문 내역 -fun NavController.navigateToOrderRecord() = navigate(UserInfoRoute.OrderRecordRoute.name) +fun NavController.navigateToOrderRecord(befRoute: UserInfoRoute) = navigate(UserInfoRoute.OrderRecordRoute.name){ + if(befRoute == UserInfoRoute.RefundRoute){ popUpTo(route = "${UserInfoRoute.RefundRoute.name}/{type}/{orderId}"){inclusive = true} } +} //환불 & 반품 내역 fun NavController.navigateToRefundRecord() = navigate(UserInfoRoute.RefundRecordRoute.name) @@ -92,7 +94,7 @@ fun NavGraphBuilder.nestedUserInfoGraph( navMyBirth: () -> Unit, navMyGender: () -> Unit, navPerfume: (Int) -> Unit, - navOrderRecord: () -> Unit, + navOrderRecord: (befRoute: UserInfoRoute) -> Unit, navRefund: (pageType: String, orderId: Int) -> Unit, navReviewWrite: (orderId: Int) -> Unit, navRefundRecord: () -> Unit, @@ -155,7 +157,7 @@ fun NavGraphBuilder.nestedUserInfoGraph( ) } composable(route = UserInfoRoute.MyBirthRoute.name) { - MyBirthRoute(navBack = navBack) + MyBirthRoute(navBack = navBack, navLogin = navLogin) } composable(route = UserInfoRoute.MyGenderRoute.name) { MyGenderRoute(navBack = navBack) @@ -164,7 +166,7 @@ fun NavGraphBuilder.nestedUserInfoGraph( MyFavoritePerfumeRoute( navPerfume = navPerfume, navHome = navHome, - onErrorHandleLoginAgain = navLogin, + navLogin = navLogin, navBack = navBack ) } @@ -192,7 +194,8 @@ fun NavGraphBuilder.nestedUserInfoGraph( type = type, orderId = orderId, navBack = navBack, - navLogin = navLogin + navLogin = navLogin, + navOrderRecord = navOrderRecord ) } composable(route = "${UserInfoRoute.RefundRecordRoute.name}") { diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/FavoriteCommentViewModel.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/FavoriteCommentViewModel.kt index 9e97bcf8b..3735521ad 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/FavoriteCommentViewModel.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/FavoriteCommentViewModel.kt @@ -9,6 +9,7 @@ import androidx.paging.cachedIn import com.hmoa.core_common.ErrorUiState import com.hmoa.core_common.Result import com.hmoa.core_common.asResult +import com.hmoa.core_domain.entity.data.MyPageCategory import com.hmoa.core_domain.repository.CommunityCommentRepository import com.hmoa.core_domain.repository.PerfumeCommentRepository import com.hmoa.core_model.response.CommunityCommentDefaultResponseDto @@ -33,7 +34,7 @@ class FavoriteCommentViewModel @Inject constructor( ) : ViewModel() { //선택된 type - private val _type = MutableStateFlow("향수") + private val _type = MutableStateFlow(MyPageCategory.향수) val type get() = _type.asStateFlow() //comment 리스트 @@ -63,18 +64,12 @@ class FavoriteCommentViewModel @Inject constructor( ) val uiState: StateFlow = type.map{ - commentPagingSource(it) + commentPagingSource(it.name) }.asResult().map{ result -> when(result){ - Result.Loading -> { - FavoriteCommentUiState.Loading - } - is Result.Success -> { - FavoriteCommentUiState.Comments(result.data) - } - is Result.Error -> { - FavoriteCommentUiState.Error - } + Result.Loading -> FavoriteCommentUiState.Loading + is Result.Success -> FavoriteCommentUiState.Comments(result.data) + is Result.Error -> FavoriteCommentUiState.Error } }.stateIn( scope = viewModelScope, @@ -83,10 +78,8 @@ class FavoriteCommentViewModel @Inject constructor( ) //type 변환 - fun changeType(newType : String){ - if (_type.value != newType) { - _type.update{newType} - } + fun changeType(newType : MyPageCategory){ + if (_type.value != newType) { _type.update{newType} } } //댓글 Paging diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyBirthViewModel.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyBirthViewModel.kt index d826c3b6a..76f9398f5 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyBirthViewModel.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyBirthViewModel.kt @@ -2,9 +2,11 @@ package com.hmoa.feature_userinfo.viewModel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.hmoa.core_common.ErrorMessageType import com.hmoa.core_common.ErrorUiState import com.hmoa.core_common.Result import com.hmoa.core_common.asResult +import com.hmoa.core_common.handleErrorType import com.hmoa.core_domain.repository.MemberRepository import com.hmoa.core_domain.usecase.GetMyUserInfoUseCase import com.hmoa.core_model.data.ErrorMessage @@ -13,7 +15,6 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn @@ -27,12 +28,6 @@ class MyBirthViewModel @Inject constructor( private val memberRepository: MemberRepository, getMyUserInfoUseCase: GetMyUserInfoUseCase ) : ViewModel() { - private var defaultBirth = 0 - - private val _birth = MutableStateFlow(null) - val birth get() = _birth.asStateFlow() - - val isEnabled = _birth.map {birth.value != defaultBirth} private var expiredTokenErrorState = MutableStateFlow(false) private var wrongTypeTokenErrorState = MutableStateFlow(false) private var unLoginedErrorState = MutableStateFlow(false) @@ -55,21 +50,23 @@ class MyBirthViewModel @Inject constructor( initialValue = ErrorUiState.Loading ) val uiState: StateFlow = errorUiState.map{ errState -> - if (errState is ErrorUiState.ErrorData && errState.generalError.first) throw Exception(errState.generalError.second) + if (errState is ErrorUiState.ErrorData && errState.isValidate()) throw Exception("") val result = getMyUserInfoUseCase() if (result.errorMessage is ErrorMessage) throw Exception(result.errorMessage!!.message) result.data!! }.asResult().map { result -> when (result) { Result.Loading -> MyBirthUiState.Loading - is Result.Success -> { - _birth.update { result.data.birth } - defaultBirth = birth.value!! - MyBirthUiState.Success - } + is Result.Success -> MyBirthUiState.Success(result.data.birth) is Result.Error -> { - if (!(errorUiState.value as ErrorUiState.ErrorData).generalError.first){ - generalErrorState.update{Pair(true, result.exception.message)} + if (result.exception.message != ""){ + handleErrorType( + error = result.exception, + onExpiredTokenError = { expiredTokenErrorState.update { true } }, + onWrongTypeTokenError = { wrongTypeTokenErrorState.update { true } }, + onUnknownError = {unLoginedErrorState.update{true}}, + onGeneralError = {generalErrorState.update{Pair(true, result.exception.message)}} + ) } MyBirthUiState.Error } @@ -80,28 +77,30 @@ class MyBirthViewModel @Inject constructor( initialValue = MyBirthUiState.Loading ) - //update local 날짜 - fun updateBirth(newBirth: Int) = _birth.update { newBirth } //remote 출생 날짜 저장 - fun saveBirth() { - if (birth.value == null) { - generalErrorState.update{Pair(true, "Input Data is NULL")} - return - } - val age = LocalDateTime.now().year - birth.value!! + 1 + fun saveBirth(birth: Int, onSuccess: () -> Unit) { + val age = LocalDateTime.now().year - birth + 1 val requestDto = AgeRequestDto(age) viewModelScope.launch { - try { - memberRepository.updateAge(requestDto) - } catch (e: Exception) { - generalErrorState.update { Pair(true, e.message) } + val result = memberRepository.updateAge(requestDto) + if (result.errorMessage != null){ + when(result.errorMessage!!.message){ + ErrorMessageType.UNKNOWN_ERROR.name -> unLoginedErrorState.update{true} + ErrorMessageType.WRONG_TYPE_TOKEN.name -> wrongTypeTokenErrorState.update{true} + ErrorMessageType.EXPIRED_TOKEN.name -> expiredTokenErrorState.update{true} + else -> generalErrorState.update{Pair(true, result.errorMessage!!.message)} + } + return@launch } + onSuccess() } } } sealed interface MyBirthUiState { data object Error : MyBirthUiState - data object Success : MyBirthUiState + data class Success( + val defaultBirth: Int + ) : MyBirthUiState data object Loading : MyBirthUiState } \ No newline at end of file diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyFavoritePerfumeViewModel.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyFavoritePerfumeViewModel.kt index 23cd261f8..a07c4f63e 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyFavoritePerfumeViewModel.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyFavoritePerfumeViewModel.kt @@ -2,34 +2,27 @@ package com.hmoa.feature_userinfo.viewModel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.hmoa.core_common.ErrorMessageType import com.hmoa.core_common.ErrorUiState import com.hmoa.core_common.Result import com.hmoa.core_common.asResult -import com.hmoa.core_domain.repository.LoginRepository +import com.hmoa.core_common.handleErrorType import com.hmoa.core_domain.repository.PerfumeRepository import com.hmoa.core_model.response.PerfumeLikeResponseDto import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.onEmpty import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class MyFavoritePerfumeViewModel @Inject constructor( - private val perfumeRepository: PerfumeRepository, - private val loginRepository: LoginRepository, + private val perfumeRepository: PerfumeRepository ) : ViewModel() { - private val authToken = MutableStateFlow(null) - private var expiredTokenErrorState = MutableStateFlow(false) private var wrongTypeTokenErrorState = MutableStateFlow(false) private var unLoginedErrorState = MutableStateFlow(false) @@ -52,29 +45,23 @@ class MyFavoritePerfumeViewModel @Inject constructor( initialValue = ErrorUiState.Loading ) - init{getAuthToken()} - val uiState: StateFlow = flow { - if (hasToken()){ - val result = perfumeRepository.getLikePerfumes() - if (result.errorMessage != null) { - throw Exception(result.errorMessage?.message) - } - emit(result.data) - } else { - throw Exception(ErrorMessageType.UNKNOWN_ERROR.message) - } + val result = perfumeRepository.getLikePerfumes() + if (result.errorMessage != null) { throw Exception(result.errorMessage!!.message) } + emit(result.data) }.asResult().map { result -> when (result) { Result.Loading -> MyFavoritePerfumeUiState.Loading is Result.Success -> MyFavoritePerfumeUiState.Like(result.data?.data ?: emptyList()) is Result.Error -> { - when (result.exception.message) { - ErrorMessageType.EXPIRED_TOKEN.message -> expiredTokenErrorState.update { true } - ErrorMessageType.WRONG_TYPE_TOKEN.message -> wrongTypeTokenErrorState.update { true } - ErrorMessageType.UNKNOWN_ERROR.message -> unLoginedErrorState.update { true } - else -> generalErrorState.update { Pair(true, result.exception.message) } } - MyFavoritePerfumeUiState.Error(result.exception.toString()) + handleErrorType( + error = result.exception, + onExpiredTokenError = { expiredTokenErrorState.update { true } }, + onWrongTypeTokenError = {wrongTypeTokenErrorState.update{true}}, + onUnknownError = {unLoginedErrorState.update{true}}, + onGeneralError = {generalErrorState.update{Pair(true, result.exception.message)}} + ) + MyFavoritePerfumeUiState.Error } } }.stateIn( @@ -82,16 +69,6 @@ class MyFavoritePerfumeViewModel @Inject constructor( started = SharingStarted.WhileSubscribed(3_000), initialValue = MyFavoritePerfumeUiState.Loading ) - - //get token - private fun getAuthToken() { - viewModelScope.launch { - loginRepository.getAuthToken().onEmpty { }.collectLatest { - authToken.value = it - } - } - } - fun hasToken() = authToken.value != null } sealed interface MyFavoritePerfumeUiState { @@ -100,7 +77,5 @@ sealed interface MyFavoritePerfumeUiState { val perfumes: List ) : MyFavoritePerfumeUiState - data class Error( - val message: String - ) : MyFavoritePerfumeUiState + data object Error: MyFavoritePerfumeUiState } \ No newline at end of file diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyGenderViewModel.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyGenderViewModel.kt index 9d5dbde69..ea629579d 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyGenderViewModel.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyGenderViewModel.kt @@ -2,9 +2,11 @@ package com.hmoa.feature_userinfo.viewModel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.hmoa.core_common.ErrorMessageType import com.hmoa.core_common.ErrorUiState import com.hmoa.core_common.Result import com.hmoa.core_common.asResult +import com.hmoa.core_common.handleErrorType import com.hmoa.core_domain.repository.MemberRepository import com.hmoa.core_domain.usecase.GetMyUserInfoUseCase import com.hmoa.core_model.request.SexRequestDto @@ -12,7 +14,6 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn @@ -25,11 +26,6 @@ class MyGenderViewModel @Inject constructor( private val memberRepository: MemberRepository, getMyUserInfoUseCase: GetMyUserInfoUseCase ) : ViewModel() { - private var defaultGender = "" - private val _gender = MutableStateFlow(null) - val gender get() = _gender.asStateFlow() - - val isEnabled = _gender.map {it != defaultGender} private var expiredTokenErrorState = MutableStateFlow(false) private var wrongTypeTokenErrorState = MutableStateFlow(false) private var unLoginedErrorState = MutableStateFlow(false) @@ -52,21 +48,23 @@ class MyGenderViewModel @Inject constructor( initialValue = ErrorUiState.Loading ) val uiState: StateFlow = errorUiState.map {errState -> - if (errState is ErrorUiState.ErrorData && errState.generalError.first) throw Exception(errState.generalError.second) + if (errState is ErrorUiState.ErrorData && errState.isValidate()) throw Exception("") val result = getMyUserInfoUseCase() if (result.errorMessage != null) {throw Exception(result.errorMessage!!.message)} result.data }.asResult().map { result -> when (result) { Result.Loading -> MyGenderUiState.Loading - is Result.Success -> { - _gender.update { result.data!!.gender } - defaultGender = result.data!!.gender - MyGenderUiState.Success - } + is Result.Success -> MyGenderUiState.Success(result.data!!.gender) is Result.Error -> { - if (!(errorUiState as ErrorUiState.ErrorData).generalError.first) { - generalErrorState.update{Pair(true, result.exception.message)} + if (result.exception.message != ""){ + handleErrorType( + error = result.exception, + onExpiredTokenError = { expiredTokenErrorState.update { true } }, + onWrongTypeTokenError = { wrongTypeTokenErrorState.update{true}}, + onUnknownError = {unLoginedErrorState.update{true}}, + onGeneralError = {generalErrorState.update{Pair(true, result.exception.message)}} + ) } MyGenderUiState.Error } @@ -76,28 +74,29 @@ class MyGenderViewModel @Inject constructor( started = SharingStarted.WhileSubscribed(3_000), initialValue = MyGenderUiState.Loading ) - - //gender 정보 수정 - fun updateGender(newGender: String) = _gender.update { newGender } //gender 정보 저장 - fun saveGender() { - if (gender.value == null) { - generalErrorState.update { Pair(true, "Gender Info is NULL") } - return - } - val requestDto = SexRequestDto(gender.value == "남성") + fun saveGender(gender: String, onSuccess: () -> Unit) { + val requestDto = SexRequestDto(gender == "남성") viewModelScope.launch { - try { - memberRepository.updateSex(requestDto) - } catch (e: Exception) { - generalErrorState.update { Pair(true, e.message) } + val result = memberRepository.updateSex(requestDto) + if (result.errorMessage != null){ + when(result.errorMessage!!.message){ + ErrorMessageType.UNKNOWN_ERROR.name -> unLoginedErrorState.update{true} + ErrorMessageType.WRONG_TYPE_TOKEN.name -> wrongTypeTokenErrorState.update{true} + ErrorMessageType.EXPIRED_TOKEN.name -> expiredTokenErrorState.update{true} + else -> generalErrorState.update{Pair(true, result.errorMessage!!.message)} + } + return@launch } + onSuccess() } } } sealed interface MyGenderUiState { data object Loading : MyGenderUiState - data object Success : MyGenderUiState + data class Success( + val defaultGender: String + ) : MyGenderUiState data object Error : MyGenderUiState } \ No newline at end of file From 8ed4112108d705811ee31d40392219224de32ab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Wed, 13 Nov 2024 14:59:04 +0900 Subject: [PATCH 20/93] =?UTF-8?q?Refactor:=20isNoteSelectedData=EC=83=81?= =?UTF-8?q?=ED=83=9C=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature_hbti/screen/NotePickScreen.kt | 76 +++++++++---------- .../viewmodel/NotePickViewmodel.kt | 26 ++++--- .../feature_hbti/NotePickViewmodelTest.kt | 6 +- 3 files changed, 53 insertions(+), 55 deletions(-) diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt index ba79240f0..98f0bdfef 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt @@ -154,46 +154,42 @@ fun NotePickGridWindow( isNoteSelectedList: List, onClickItem: (index: Int, value: Boolean, data: NoteSelect) -> Unit ) { - if (notes?.data == null) { - Text("데이터가 없습니다") - } else { - LazyVerticalGrid(columns = GridCells.Fixed(3), verticalArrangement = Arrangement.SpaceBetween) { - itemsIndexed(notes?.data ?: emptyList()) { index, item -> - Column( - modifier = Modifier.padding(vertical = 10.dp).padding(horizontal = 5.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - NoteImageView( - imageUrl = item.productPhotoUrl, - width = 74f, - height = 74f, - backgroundColor = Color.Transparent, - contentScale = ContentScale.Crop, - onClicked = { - onClickItem( - index, - !isNoteSelectedList[index].isSelected, - isNoteSelectedList[index] - ) - }, - isRecommanded = item.isRecommended, - index = isNoteSelectedList[index].nodeFaceIndex, - isSelected = isNoteSelectedList[index].isSelected - ) - Text( - text = item.productName, - style = TextStyle(fontFamily = pretendard, fontWeight = FontWeight.SemiBold, fontSize = 14.sp), - modifier = Modifier.padding(top = 12.dp, bottom = 5.dp) - ) - Text( - text = item.productDetails, - style = TextStyle(fontFamily = pretendard, fontWeight = FontWeight.Normal, fontSize = 12.sp) - ) - Text( - text = "(총 ${item.price}원)", - style = TextStyle(fontFamily = pretendard, fontWeight = FontWeight.Normal, fontSize = 12.sp) - ) - } + LazyVerticalGrid(columns = GridCells.Fixed(3), verticalArrangement = Arrangement.SpaceBetween) { + itemsIndexed(notes?.data ?: emptyList()) { index, item -> + Column( + modifier = Modifier.padding(vertical = 10.dp).padding(horizontal = 5.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + NoteImageView( + imageUrl = item.productPhotoUrl, + width = 74f, + height = 74f, + backgroundColor = Color.Transparent, + contentScale = ContentScale.Crop, + onClicked = { + onClickItem( + index, + !isNoteSelectedList.get(index).isSelected, + isNoteSelectedList.get(index) + ) + }, + isRecommanded = item.isRecommended, + index = isNoteSelectedList.get(index).nodeFaceIndex, + isSelected = isNoteSelectedList.get(index).isSelected + ) + Text( + text = item.productName, + style = TextStyle(fontFamily = pretendard, fontWeight = FontWeight.SemiBold, fontSize = 14.sp), + modifier = Modifier.padding(top = 12.dp, bottom = 5.dp) + ) + Text( + text = item.productDetails, + style = TextStyle(fontFamily = pretendard, fontWeight = FontWeight.Normal, fontSize = 12.sp) + ) + Text( + text = "(총 ${item.price}원)", + style = TextStyle(fontFamily = pretendard, fontWeight = FontWeight.Normal, fontSize = 12.sp) + ) } } } diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/NotePickViewmodel.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/NotePickViewmodel.kt index 431c0cb5e..184b11479 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/NotePickViewmodel.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/NotePickViewmodel.kt @@ -21,11 +21,11 @@ class NotePickViewmodel @Inject constructor( ) : ViewModel() { private var _topRecommendedNoteState = MutableStateFlow("") private var _noteProductsState = MutableStateFlow(null) - private var _noteSelectDataState = MutableStateFlow>(listOf()) + private var _isNoteSelectDataState = MutableStateFlow>(listOf()) private var _isNextButtonAvailableState = MutableStateFlow(false) val topRecommendedNoteState: StateFlow = _topRecommendedNoteState val noteProductState: StateFlow = _noteProductsState - val noteSelectDataState: StateFlow> = _noteSelectDataState + val isNoteSelectDataState: StateFlow> = _isNoteSelectDataState val isNextButtonAvailableState: StateFlow = _isNextButtonAvailableState val selectedIds = MutableStateFlow>(emptyList()) private var _noteOrderIndex = MutableStateFlow(1) @@ -38,7 +38,7 @@ class NotePickViewmodel @Inject constructor( combine( _topRecommendedNoteState, _noteProductsState, - _noteSelectDataState, + _isNoteSelectDataState, _noteOrderIndex ) { topRecommendedNote, notes, noteSelectData, noteOrderIndex -> NotePickUiState.NotePickData( @@ -73,12 +73,11 @@ class NotePickViewmodel @Inject constructor( init { viewModelScope.launch(Dispatchers.IO) { getTopRecommendedNote() - launch { getNoteProducts() }.join() - initializeIsNoteSelectedList(_noteProductsState.value) + getNoteProducts() } } - fun initializeIsNoteSelectedList(noteList: ProductListResponseDto?) { + fun initializeIsNoteSelectedList(noteList: ProductListResponseDto?, onUpdateProducts: () -> Unit) { var initializedList = MutableList(noteList?.data?.size ?: 0) { NoteSelect( @@ -99,7 +98,8 @@ class NotePickViewmodel @Inject constructor( ) ) } - _noteSelectDataState.update { initializedList } + _isNoteSelectDataState.update { initializedList } + onUpdateProducts() } suspend fun getTopRecommendedNote() { @@ -115,7 +115,9 @@ class NotePickViewmodel @Inject constructor( when (result) { is com.hmoa.core_common.Result.Success -> { viewModelScope.launch(Dispatchers.IO) { - _noteProductsState.update { result.data.data } + initializeIsNoteSelectedList( + result.data.data, + onUpdateProducts = { _noteProductsState.update { result.data.data } }) } } @@ -137,7 +139,7 @@ class NotePickViewmodel @Inject constructor( } fun postNoteSelected(onSuccess: () -> Unit) { - val requestDto = _noteSelectDataState.value.filter { it.isSelected }.map { it.productId } + val requestDto = _isNoteSelectDataState.value.filter { it.isSelected }.map { it.productId } selectedIds.update { requestDto } viewModelScope.launch(Dispatchers.IO) { flow { @@ -171,10 +173,10 @@ class NotePickViewmodel @Inject constructor( value: Boolean, data: NoteSelect, ) { - var noteSelectData = makeDeepCopyOfNoteSelectData(_noteSelectDataState.value) + var noteSelectData = makeDeepCopyOfNoteSelectData(_isNoteSelectDataState.value) noteSelectData = changeNoteSelectData(index, value, data, noteSelectData) noteSelectData = reorderNoteFaceIndex(noteSelectData) - _noteSelectDataState.update { noteSelectData } + _isNoteSelectDataState.update { noteSelectData } _noteOrderIndex.update { countSelectedNote(noteSelectData) } handleIsNextButtonAvailableState(noteSelectData = noteSelectData) } @@ -266,4 +268,4 @@ sealed interface NotePickUiState { val noteSelectData: List, val noteOrderIndex: Int, ) : NotePickUiState -} \ No newline at end of file +} diff --git a/feature-hbti/src/test/java/com/hmoa/feature_hbti/NotePickViewmodelTest.kt b/feature-hbti/src/test/java/com/hmoa/feature_hbti/NotePickViewmodelTest.kt index 6fef77990..e211296cb 100644 --- a/feature-hbti/src/test/java/com/hmoa/feature_hbti/NotePickViewmodelTest.kt +++ b/feature-hbti/src/test/java/com/hmoa/feature_hbti/NotePickViewmodelTest.kt @@ -144,7 +144,7 @@ class NotePickViewmodelTest : TestCase() { } launch { viewmodel.getNoteProducts() }.join() launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value) }.join() - Assert.assertEquals(expectedNoteSelectData, viewmodel.noteSelectDataState.value) + Assert.assertEquals(expectedNoteSelectData, viewmodel.isNoteSelectDataState.value) } @Test @@ -177,7 +177,7 @@ class NotePickViewmodelTest : TestCase() { isRecommended = targetNode.isRecommended, nodeFaceIndex = null ) - Assert.assertEquals(expectedNoteSelectData, viewmodel.noteSelectDataState.value) + Assert.assertEquals(expectedNoteSelectData, viewmodel.isNoteSelectDataState.value) } @Test @@ -316,4 +316,4 @@ class NotePickViewmodelTest : TestCase() { //Then: 버튼의 사용가능여부 = false이다 Assert.assertEquals(false, viewmodel.isNextButtonAvailableState.value) } -} \ No newline at end of file +} From 1dc9e4110b26bf4ee118ef54fca2fa764d2aa479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Wed, 13 Nov 2024 18:53:07 +0900 Subject: [PATCH 21/93] =?UTF-8?q?fix:=20Hbti=20ProgressBar=20=EB=A6=AC?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EC=A7=80=EC=85=98=20=EC=B5=9C=EC=A0=81?= =?UTF-8?q?=ED=99=94=20=EB=B0=8F=20UI=20=EB=B2=84=EA=B7=B8=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/hmoa/core_common/CommonFunctions.kt | 7 ++++--- .../hmoa/core_designsystem/component/ProgressBar.kt | 11 ++++++----- .../hmoa/core_domain/entity/data/HbtiQuestionItems.kt | 5 +++-- .../com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt | 11 ++++------- .../screen/PerfumeRecommendationScreen.kt | 6 +++--- .../feature_hbti/viewmodel/HbtiSurveyViewmodel.kt | 9 ++++++--- 6 files changed, 26 insertions(+), 23 deletions(-) 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 index 7c160db25..eaeffa3f7 100644 --- a/core-common/src/main/java/com/hmoa/core_common/CommonFunctions.kt +++ b/core-common/src/main/java/com/hmoa/core_common/CommonFunctions.kt @@ -27,8 +27,9 @@ fun calculateProgressStepSize(list: List?): Float { } } -fun calculateHbtiProgressStepSize(list: List?): Float { - 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 { @@ -66,4 +67,4 @@ fun absolutePath(context: Context, uri: Uri): String? { return null } return file.absolutePath -} \ 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-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 index f700ce367..acaf63dc2 100644 --- 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 @@ -3,5 +3,6 @@ package com.hmoa.core_domain.entity.data typealias QuestionPageIndex = Int data class HbtiQuestionItems( - val hbtiQuestions: MutableMap -) \ No newline at end of file + val hbtiQuestions: MutableMap, + val questionCounts: Int +) diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt index 49aeab22b..f9fa85495 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt @@ -112,15 +112,13 @@ fun HbtiSurveyContent( var currentProgress by remember { mutableStateOf(0f) } var targetProgress by remember { mutableStateOf(0f) } val scope = rememberCoroutineScope() // Create a coroutine scope - val pageContent = hbtiQuestionItems?.hbtiQuestions?.values?.map { it } - val additionalProgress = calculateHbtiProgressStepSize(pageContent) val pagerState = - rememberPagerState(initialPage = 0, pageCount = { hbtiQuestionItems?.hbtiQuestions?.values?.size ?: 0 }) - + rememberPagerState(initialPage = 0, pageCount = { hbtiQuestionItems?.questionCounts ?: 0 }) + val additionalProgress = calculateHbtiProgressStepSize(hbtiQuestionItems?.questionCounts ?: 13) fun addProgress() { targetProgress += additionalProgress scope.launch { - loadProgress { progress -> + loadProgress(additionalProgress) { progress -> if (currentProgress <= targetProgress) { currentProgress += progress } @@ -131,7 +129,7 @@ fun HbtiSurveyContent( fun subtractProgress() { targetProgress -= additionalProgress scope.launch { - loadProgress { progress -> + loadProgress(additionalProgress) { progress -> if (currentProgress >= targetProgress) { currentProgress -= progress } @@ -220,7 +218,6 @@ fun HbtiSurveyContent( isEnabled = isNextQuestionAvailable?.get(pagerState.currentPage) ?: true, btnText = "다음", onClick = { - addProgress() scope.launch { pagerState.animateScrollToPage(pagerState.currentPage + 1) } diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/PerfumeRecommendationScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/PerfumeRecommendationScreen.kt index bbece9b55..993c52b1e 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/PerfumeRecommendationScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/PerfumeRecommendationScreen.kt @@ -121,7 +121,7 @@ fun PerfumeRecommendationScreen( fun addProgress() { targetProgress += additionalProgress scope.launch { - loadProgress { progress -> + loadProgress(additionalProgress) { progress -> if (currentProgress <= targetProgress) { currentProgress += progress } @@ -132,7 +132,7 @@ fun PerfumeRecommendationScreen( fun subtractProgress() { targetProgress -= additionalProgress scope.launch { - loadProgress { progress -> + loadProgress(additionalProgress) { progress -> if (currentProgress >= targetProgress) { currentProgress -= progress } @@ -358,4 +358,4 @@ private fun NoteScreen( @Preview @Composable private fun PreviewScreen() { -} \ No newline at end of file +} diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiSurveyViewmodel.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiSurveyViewmodel.kt index fc518a86f..21ee75fb9 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiSurveyViewmodel.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiSurveyViewmodel.kt @@ -3,9 +3,9 @@ package com.hmoa.feature_hbti.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.hmoa.core_common.* -import com.hmoa.core_domain.repository.SurveyRepository import com.hmoa.core_domain.entity.data.HbtiQuestionItem import com.hmoa.core_domain.entity.data.HbtiQuestionItems +import com.hmoa.core_domain.repository.SurveyRepository import com.hmoa.core_model.request.NoteResponseDto import com.hmoa.core_model.request.SurveyRespondRequestDto import com.hmoa.core_model.response.SurveyQuestionsResponseDto @@ -127,7 +127,8 @@ class HbtiSurveyViewmodel @Inject constructor( HbtiQuestionItems( hbtiQuestions = initializeHbtiQuestionItemsState( result.data.data - ) + ), + questionCounts = result.data.data?.questions?.size ?: 0 ) } _hbtiAnwserIdsState.update { initializeHbtiAnswerIdsState(result.data.data) } @@ -230,11 +231,13 @@ class HbtiSurveyViewmodel @Inject constructor( fun getUpdatedHbtiQuestionItems(page: Int, newHbtiQuestionItem: HbtiQuestionItem): HbtiQuestionItems { val newHbtiQuestionItems = mutableMapOf() + var count = 0 _hbtiQuestionItemsState.value?.hbtiQuestions?.set(page, newHbtiQuestionItem) _hbtiQuestionItemsState.value?.hbtiQuestions?.map { newHbtiQuestionItems[it.key] = it.value + count += 1 } - return HbtiQuestionItems(hbtiQuestions = newHbtiQuestionItems) + return HbtiQuestionItems(hbtiQuestions = newHbtiQuestionItems, questionCounts = count) } fun updatedIsNextQuestionAvailable( From 1cace448dc898f5a77f434babeac294762a578b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Wed, 13 Nov 2024 19:12:24 +0900 Subject: [PATCH 22/93] =?UTF-8?q?Design:=20Hbti=20=ED=96=A5=EB=A3=8C=20?= =?UTF-8?q?=EC=84=A0=ED=83=9D=ED=99=94=EB=A9=B4=20=EB=94=94=ED=85=8C?= =?UTF-8?q?=EC=9D=BC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature_hbti/screen/NotePickScreen.kt | 33 +++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt index 98f0bdfef..d948b891b 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.layout.ContentScale 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.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel @@ -120,13 +121,36 @@ fun NoteContent( ) { Text( "추천받은 카테고리는 '${topRecommendedNote}'입니다.\n그 외에 원하는 시향카드 카테고리를\n선택해주세요", - modifier = Modifier.padding(bottom = 32.dp, top = 36.dp), + modifier = Modifier.padding(bottom = 12.dp, top = 36.dp), style = TextStyle( fontSize = 20.sp, fontWeight = FontWeight.SemiBold, fontFamily = pretendard ) ) + Row { + Text( + "*", + modifier = Modifier.padding(bottom = 28.dp), + style = TextStyle( + color = CustomColor.gray5, + fontSize = 9.sp, + fontWeight = FontWeight.Medium, + fontFamily = pretendard + ), + textAlign = TextAlign.Start + ) + Text( + "향료 1개당 900원", + modifier = Modifier.padding(bottom = 28.dp), + style = TextStyle( + color = CustomColor.gray5, + fontSize = 14.sp, + fontWeight = FontWeight.Medium, + fontFamily = pretendard + ) + ) + } NotePickGridWindow( notes = noteList, isNoteSelectedList = isNoteSelectedList, @@ -184,7 +208,12 @@ fun NotePickGridWindow( ) Text( text = item.productDetails, - style = TextStyle(fontFamily = pretendard, fontWeight = FontWeight.Normal, fontSize = 12.sp) + style = TextStyle( + fontFamily = pretendard, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + textAlign = TextAlign.Center + ) ) Text( text = "(총 ${item.price}원)", From 124959d0439fb1f0305ae40dfc1ebf9078495718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Wed, 13 Nov 2024 19:27:39 +0900 Subject: [PATCH 23/93] =?UTF-8?q?Fix:=20nullable=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EB=88=84=EB=9D=BD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/hmoa/feature_home/viewmodel/HomeViewModel.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/feature-home/src/main/java/com/hmoa/feature_home/viewmodel/HomeViewModel.kt b/feature-home/src/main/java/com/hmoa/feature_home/viewmodel/HomeViewModel.kt index f68c93cea..017faac63 100644 --- a/feature-home/src/main/java/com/hmoa/feature_home/viewmodel/HomeViewModel.kt +++ b/feature-home/src/main/java/com/hmoa/feature_home/viewmodel/HomeViewModel.kt @@ -34,16 +34,16 @@ class HomeViewModel @Inject constructor( is Result.Success -> { _firstMenuWithBannerState.update { it } _firstMenuWithBannerState.value = BannerWithFirstMenuState.Data( - bannerImg = it.data.data!!.mainImage, - bannerTitle = it.data.data!!.banner, - firstMenu = it.data.data!!.firstMenu + bannerImg = it.data.data?.mainImage, + bannerTitle = it.data.data?.banner, + firstMenu = it.data.data?.firstMenu ) } - is Result.Error -> {}//TODO() + is Result.Error -> {} is Result.Loading -> { BannerWithFirstMenuState.Loading - }//TODO() + } } } } @@ -90,4 +90,4 @@ class HomeViewModel @Inject constructor( data object Error : BottomMenuState } -} \ No newline at end of file +} From 9d04ab64d8d9b6c162dca26db501a7aa072cfb1a Mon Sep 17 00:00:00 2001 From: Lee YongIn <67788699+LeeYongIn0517@users.noreply.github.com> Date: Fri, 15 Nov 2024 10:48:58 +0900 Subject: [PATCH 24/93] =?UTF-8?q?Feature/hbti=20=EB=B2=84=EA=B7=B8=20?= =?UTF-8?q?=EB=B0=8F=20HBTI=20UI=20=EC=88=98=EC=A0=95=20(#183)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Design: 공백 수정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Release 1.0.0(18) 출시 (#147) * Feature-Magazine Init * Chore: Manifest 정리 * Chore: 기본 의존성 설정 * Chore: Test 관련 의존성 정리 * Chore: Compose 설정 * Feat: Response Dto 추가 * Feat: Magazine Screen 추가 * Feat: Magazine Service 추가 * Feat: Magazine Service DI 추가 * Resource: Floating Action Button Open Icon 추가 * Feat: Magazine DataStore 추가 * Fix: Response 타입 수정 * Feat: Data Store DI * Feat: Repository DI * Feat: Magazine Repository 추가 * Feat: 최신 향수 받아오는 API 추가 * Feat: 최신 향수 받아오는 DTO 추가 * Resource: 공유 아이콘 추가 * Feat: Magazine ViewModel 로직 추가 * Design: TopBar 투명도 파라미터 추가 * Rename: 파일 명 변경 * Design: 투명도 추가 * Design: Magazine Tag 추가 * Resource: 아이콘 resource 추가 * Fix: Response 타입 변경 * Chore: Magazine 의존성 추가 * Feat: Magazine Navigation 추가 * Fix: Bottom Navigation 내용 변경 * Feat: Magazine 상세 화면 추가 * Feat: Magazine Paging 추가 * Feat: Magazine Route 클래스 추가 * Feat: Magazine 상세 비즈니스 로직 추가 * Fix: Conflict 수정 * Fix: Paging 오류 수정 * Design: title 색상 파라미터 추가 * Design: title 색상 파라미터 추가 * Design: review content 위치 변경 * Design: Content 글자 수 제한 * Design: title 글자 수 제한 * Fix: 개행문자 수정 * Feat: Navigation 이벤트 추가 * Feat: Magazine 상세 화면 추가 * Feat: Magazine 상세 화면 비즈니스 로직 추가 * Feat: Navigation 이벤트 추가 * Fix: 데이터 순서에 따른 오류 수정 * Design: Tag UI 수정 * Design: Space 크기 조절 * Feat: 좋아요 update 이벤트 추가 * Fix: Navigation 이벤트 파라미터 추가 * Feat: Navigation 이벤트 파라미터 추가 * Design: Magazine UI 위치 수정 * Fix: Magazine Image 추가 * Resource: Magazine Icon 추가 * Design: 바텀 네비게이션 UI 수정 * Feat: Navigation SingleTop 옵션 추가 * Feat: 좋아요 한 향수 페이지 위치 변동 * FIX: 비로그인 에러다이얼로그 동작 오류 수정 * Fix: Navigation 누락 오류 수정 * Fix: err state 누락 오류 수정 * Fix: navigation 누락 수정 * Design: UI 간격 수정 * Gradle: Material 의존성 추가 * Design: 수정 모달 추가 * Refactor: Dialog 팝업 방식 변경 * FIX: 좋아요 리프레싱 시 리컴포지션 안되는 오류 수정 * Rename: 이름 혼동 방지 * Rename: 이름 혼동 방지 * Fix: Dialog Pop up 시 깜빡거림 수정 * Feat: 향수페이지 댓글 오류 수정 * Fix: 향수 페이지 댓글 상태관리 변화 오류 수정 * Delete: 사용하지 않는 상태관리 변수 삭제 * Update README.md * Resource: Font 추가 * Create android.yml develop 브랜치로 코드 푸시, PR 시 빌드되는 기능 * Feat: 자동 빌드 기능 테스트 구문 * Update android.yml * Feat: 자바 버전 11 -> 17 * Fix: CI환경 빌드에 local.properties 파일 동적 생성 기능 추가 * Fix: 경로 오류 수정 * Feat: 모든 모듈의 local-properties파일 삭제 명령파일 생성 * Fix: app 모듈왜 local.properties를 사용하는 모듈도 파일 동적생성 적용 * Chore: 서브 모듈 추가 * Delete: mylibrary 모듈 삭제 * Chore: AndroidSecretSecure 서브 레포지토리 추가 * Revert "Delete: mylibrary 모듈 삭제" This reverts commit cc0c0fd6d21b7f3d941ed11ab515ff2bf6b8e8ab. * Revert "Chore: 서브 모듈 추가" This reverts commit 95cc85845823843a72eb29a6b65a001b99947c6f. * Fix: 소셜 토큰 api 호출 오류 수정 * Ignore * Fix: lateinit 삭제 및 초기화 값 지정 * Fix: IndexOutOfBoundException방지 구문 추가 * Chore: google-service.json 파일 추가 * Rename * Chore: NATIVE_APP_KEY 적용 * Chore: 버전 증가 6->7 * Feat: 토큰 유무 검사 로직 수정 * Feat: 토큰 가져오는 비동기 작업 -> 동기로 변경 * Fix: 토큰 갱신 작업 대기방식을 동기적으로 변경 * Fix: 스트림 닫힘 오류 원인 부분 해결 * Revert "Feat: 토큰 가져오는 비동기 작업 -> 동기로 변경" This reverts commit f56f46f1000603260a6f143dd4304ffc1b4750bf. * Fix: postFcmToken NullPointException 원인구문 삭제 * Fix: 인터셉터 토큰 추가동작 수정 비동기 -> 동기 * Chore: v1.0.0 버전코드 수정 (7->8) * Fix: native app key, string value로 변경 * Fix: HttpLoggingInterceptor 제거 - IllgalStateException 해결을 위해 지워봄 * Refactor: HPediaDesc api호출 분리 및 CastException 해결 * Chore: 버전코드 수정(8->9) * Chore: 버전코드 수정 (9->10) * Fix: 변수 명 오류 * Chore: 버전코드 수정(10->11) * Fix: 카카오 앱 키 참조 방식 변경 * Chore: 버전코드 수정(11->12) * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Chore: core-common 의존성 추가 * Delete: 토큰 재발급 임시 로직 삭제 * HotFix: Authenticator 토큰 재발급 및 에러메세지 전달 기능 수정 * Fix: Authenticator 적용 * Fix: api 호출부에 Authenticator 적용 * Delete: 안쓰는 api 삭제 * Refactor: FCM 초기화 및 초기 라우팅 코드 함수로 분리 * Delete: 임시 refreshToken 코드 관련 api 삭제 * Rename: 토큰 관련 클래스 의존성 주입 모듈 이름 수정 * Fix: 토큰 동적 할당 시점 변경 * Fix: 로그인 화면 이동 네비게이션 변경 * Chore: 버전 변경 (v1.1.1 -> v1.1.2) * Chore: ci,cd 구문 변경 및 action.yml 파일 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: ci/cd 워크플로우 임시로 주석처리 및 사용중지 * Chore: android.yml 워크플로우 일시중지 (#164) * Chore: CI 구문 롤백 및 오작동 CI/CD 임시폴더로 분리 * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 * v1.1.1 버전 master로 머지합니다 (#163) * Feat: Fcm 관련 함수 추가 * Chore: FCM 모듈 의존성 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Chore: fcm 모듈 환경 설정 추가 * Feat: App Navigation 이벤트 추가 * Chore: FCM 모듈 환경 설정 * Resource: 아이콘 추가 * Feat: 알림 수신 여부 이벤트 추가 * Feat: 알림 화면 추가 * Feat: 알림 화면 비즈니스 로직 추가 * Feat: FCM 모듈 추가 * Feat: 알림 Response 모델 추가 * Feat: 알림 화면 네비게이션 추가 * Design: 읽음 여부에 따른 배경색 조절 * Test: 테스트 코드 추가 * Feat: App Scheme 추가 * Feat: Deeplink Navigation 추가 * Ignore * Delete: sample-app 모듈 삭제 * Delete: Hhmoa_android_secret 로컬 폴더 삭제 * Design: Button 컴포넌트 disabled color 이름 적용 * Feat: Hbti설문 아이템 컴포넌트 추가 * Feat: ProgressBar 컴포넌트 생성 * Feat: VerticalStepBar 컴포넌트 생성 * Design: 홈화면 상단 로고 아이콘 추가 * Design: 디자인시스템 모듈 내 컴포넌트에 pretendard 폰트 적용 * Feat: profile 속성 추가 * Feat: send top notification 파라미터 수정 * Feat: profile 속성 추가 * Chore: Activity single top 속성 설정 * Fix: Error Ui State 업데이트 안되는 오류 수정 * Feat: deeplink 처리 함수 추가 * Refactor: Community, HPedia 네비게이션 분리 * Refactor: Community, HPedia 네비게이션 분리 * Feat: deeplink 설정 * Fix: 경로 설정 오류 수정 * Fix: deeplink 위치 오류 수정 * Fix: Response Dto 형식 오류 수정 * Design: Profile 반영 * Feat: 선택 이벤트 추가 * Feat: Navigation 설정 * Feat: 읽음 처리 함수 추가 * Fix: read 변경 가능하도록 수정 * Test: import 수정 * ignore: git pull * Design: 색상 변경 * Feat: NoteImageItem 생성 * Feat: 권한 설정 여부 정보를 확인 * Feat: 권한 설정 함수 추가 * Ignore * Ignore * Feat: feature-hbti 모듈 생성 * Feat:선택지 무효화 기능 추가 및 SurveyOptionList로 수정 * Rename: SurveyOptionItem -> SurveyOptionList * Feat: ProgressBarPreview에 +/- 효과 추가 * Chore: gradle 의존성 추가 * Fix: intent 이름 변경 * Feat: 알림 선택 시 읽음 처리 이벤트 추가 * Feat: 포그라운드 알림 처리 * Fix: Navigation Deeplink 오류 수정 * Chore: mockito 라이브러리 추가 * Feat: HbtiScreen 추가 * Chore: compose material 및 preview 라이브러리 추가 * Feat: Hbti화면 완성 * Design: 향BTI 화면 디자인 구성 완료 * Feat: 향BTI 테스트 데이터계층 클래스 생성 * Rename: SurveyAnswerResponseDto -> SurveyOptionResponseDto * Feat: fcm token 저장 함수 추가 * Fix: 파라미터 이름 오류 수정 * Fix: 토큰 저장 알고리즘 수정 * Feat: 향수 추천 화면 추가 * Design: 공백 수정 * Feat: 데이터 계층 hilt 주입코드 추가 * Feat: HbtiSurvey 화면 추가(미완성) * Feat: 가격 선택 화면 추가 * Design: 아이템 간 간격 조절 * Rename: 컴포넌트 이름 변경 * Rename: 컴포넌트 이름 변경 * Feat: 향료 선택 화면 추가 * Refactor: 화면 구성 변경 * Fix: 파라미터 변경 * Resource: icon 추가 * Fix: 파라미터 수정 * Feat: 향료 선택 화면 추가 * Style: 공백 스타일 변경 * Fix: 푸쉬 오류 수정 * Style: 코드 스타일 변경 * Feat: 향수 추천 결과 화면 추가 * Rename: 컴포넌트 이름 변경 * Ignore * Delete * Chore: test 라이브러리 추가 * Feat: HbtiSurveyViewmodel 생성 * Test: HbtiSurveyViewModel 테스트 생성 * Test: 테스트 기대값 수정 * Feat: Dto 추가 * Feat: Api 추가 * Style: 코드 라인 변경 * Feat: 비즈니스 로직 추가 * Remove: 삭제 * Feat: 향료 데이터 클래스 추가 * Comment: 주석 추가 * Fix: 서버에 정보 전달 로직 임의 대체 * Rename: 함수 명 변경 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: UI 상태 기준 분기 * Feat: Navigation 설정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: android.yml 워크플로우 일시중지 (#164) * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Fix: 파라미터 명시적으로 구분 * Fix: RouteScreen 파라미터 변수명 변경 반영 * Chore: 버전코드 수정 22->23 * Ignore * Fix: 백업데이터 설정 해제 * Chore: 버전 업데이트 * Release 1.1.2버전 master로 푸시 (#167) * Feat: Fcm 관련 함수 추가 * Chore: FCM 모듈 의존성 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Chore: fcm 모듈 환경 설정 추가 * Feat: App Navigation 이벤트 추가 * Chore: FCM 모듈 환경 설정 * Resource: 아이콘 추가 * Feat: 알림 수신 여부 이벤트 추가 * Feat: 알림 화면 추가 * Feat: 알림 화면 비즈니스 로직 추가 * Feat: FCM 모듈 추가 * Feat: 알림 Response 모델 추가 * Feat: 알림 화면 네비게이션 추가 * Design: 읽음 여부에 따른 배경색 조절 * Test: 테스트 코드 추가 * Feat: App Scheme 추가 * Feat: Deeplink Navigation 추가 * Ignore * Delete: sample-app 모듈 삭제 * Delete: Hhmoa_android_secret 로컬 폴더 삭제 * Design: Button 컴포넌트 disabled color 이름 적용 * Feat: Hbti설문 아이템 컴포넌트 추가 * Feat: ProgressBar 컴포넌트 생성 * Feat: VerticalStepBar 컴포넌트 생성 * Design: 홈화면 상단 로고 아이콘 추가 * Design: 디자인시스템 모듈 내 컴포넌트에 pretendard 폰트 적용 * Feat: profile 속성 추가 * Feat: send top notification 파라미터 수정 * Feat: profile 속성 추가 * Chore: Activity single top 속성 설정 * Fix: Error Ui State 업데이트 안되는 오류 수정 * Feat: deeplink 처리 함수 추가 * Refactor: Community, HPedia 네비게이션 분리 * Refactor: Community, HPedia 네비게이션 분리 * Feat: deeplink 설정 * Fix: 경로 설정 오류 수정 * Fix: deeplink 위치 오류 수정 * Fix: Response Dto 형식 오류 수정 * Design: Profile 반영 * Feat: 선택 이벤트 추가 * Feat: Navigation 설정 * Feat: 읽음 처리 함수 추가 * Fix: read 변경 가능하도록 수정 * Test: import 수정 * ignore: git pull * Design: 색상 변경 * Feat: NoteImageItem 생성 * Feat: 권한 설정 여부 정보를 확인 * Feat: 권한 설정 함수 추가 * Ignore * Ignore * Feat: feature-hbti 모듈 생성 * Feat:선택지 무효화 기능 추가 및 SurveyOptionList로 수정 * Rename: SurveyOptionItem -> SurveyOptionList * Feat: ProgressBarPreview에 +/- 효과 추가 * Chore: gradle 의존성 추가 * Fix: intent 이름 변경 * Feat: 알림 선택 시 읽음 처리 이벤트 추가 * Feat: 포그라운드 알림 처리 * Fix: Navigation Deeplink 오류 수정 * Chore: mockito 라이브러리 추가 * Feat: HbtiScreen 추가 * Chore: compose material 및 preview 라이브러리 추가 * Feat: Hbti화면 완성 * Design: 향BTI 화면 디자인 구성 완료 * Feat: 향BTI 테스트 데이터계층 클래스 생성 * Rename: SurveyAnswerResponseDto -> SurveyOptionResponseDto * Feat: fcm token 저장 함수 추가 * Fix: 파라미터 이름 오류 수정 * Fix: 토큰 저장 알고리즘 수정 * Feat: 향수 추천 화면 추가 * Design: 공백 수정 * Feat: 데이터 계층 hilt 주입코드 추가 * Feat: HbtiSurvey 화면 추가(미완성) * Feat: 가격 선택 화면 추가 * Design: 아이템 간 간격 조절 * Rename: 컴포넌트 이름 변경 * Rename: 컴포넌트 이름 변경 * Feat: 향료 선택 화면 추가 * Refactor: 화면 구성 변경 * Fix: 파라미터 변경 * Resource: icon 추가 * Fix: 파라미터 수정 * Feat: 향료 선택 화면 추가 * Style: 공백 스타일 변경 * Fix: 푸쉬 오류 수정 * Style: 코드 스타일 변경 * Feat: 향수 추천 결과 화면 추가 * Rename: 컴포넌트 이름 변경 * Ignore * Delete * Chore: test 라이브러리 추가 * Feat: HbtiSurveyViewmodel 생성 * Test: HbtiSurveyViewModel 테스트 생성 * Test: 테스트 기대값 수정 * Feat: Dto 추가 * Feat: Api 추가 * Style: 코드 라인 변경 * Feat: 비즈니스 로직 추가 * Remove: 삭제 * Feat: 향료 데이터 클래스 추가 * Comment: 주석 추가 * Fix: 서버에 정보 전달 로직 임의 대체 * Rename: 함수 명 변경 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: UI 상태 기준 분기 * Feat: Navigation 설정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: android.yml 워크플로우 일시중지 (#164) * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Revert "Chore: 버전 업데이트" This reverts commit 031fc2f141d3ffbc07b0954eda874c58d7e1c834. * Revert "Fix: 백업데이터 설정 해제" This reverts commit bb68a8d265be89d74bcc2feed66baca5355cd475. * HotFix: 카카오 sdk 버전 업그레이드 * HotFix: 카카오 sdk 버전 업그레이드 (#170) * HotFix: 카카오 sdk 버전 업그레이드 * Feat: gradlew clean 작업 추가 * Delete * Delete: refreshToken 추상메서드 삭제 * Delete: 토큰 리프레싱 임시방안 코드 삭제 * HotFix: 카카오 sdk 버전 업그레이드 (#174) * Hotfix/community (#176) * Fix: 좋아요 반영 안되는 오류 수정 * Fix: response에 wrapping 추가 * Design: 내용 및 사진 누락 추가 * Fix: response wrapping * Design: 디자인 누락 추가 * Refactor: 불필요 로직 삭제 * Feat: 파라미터 명 변경 * Design: 버튼 가려지는 현상 수정 * Fix: hbti 향료개수 자유선택 후 튕기는 현상 수정 * Fix: hbti 향료 선택결과 제출로직 변경 * Fix: hbti 향료선택화면 하단버튼 disabled 상태관리 추가 * Fix: hbti 향료 카테고리 선택화면 로직 변경 반영 * Test: hbti 향료 카테고리 선택화면 로직 변경사항 테스트 * Design: 백버튼 추가 * Feat: 향료 제품 가격 추가 * Refactor: 플래그 제거 및 콜백으로 대체 * Design: 디자인 마진 변경 * Design: Topbar 배경 수정 * Feat: hbti 홈화면 메타데이터 추가 및 기존 데이터 리팩토링 * Design: 홈 디자인 변경 반영 * Design: Topbar 디폴트 배경 변경 * Feat: 로그인 유무 확인 코드 추가 * Design: 스크롤 초기 위치 수정 * Chore: 버전 코드 변경 (24 -> 25) * Design: 향모아 사업자 정보 추가 * Fix: hbti 메타데이터 요청 오류 임시 주석처리 * Chore: 데이터백업설정 변경 * Chore: 테스트 버전 업그레이드 25->27 * chore: gitignore 파일 추가 * chore: 주석해제 * Feat: 상품 구매 여부 확인 다이얼로그 추가 * Feat: Hbti 설문 양옆 스크롤 기능 추가 * Delete: 주석 삭제 * Fix: LazyColumn으로 변경 후 스크롤위치 초기화 적용 * Refactor: isNoteSelectedData상태 업데이트 함수 수정 * fix: Hbti ProgressBar 리컴포지션 최적화 및 UI 버그 개선 * Design: Hbti 향료 선택화면 디테일 변경 * Fix: nullable 처리 누락 수정 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> --- .gitignore | 2 + .idea/deploymentTargetSelector.xml | 4 +- .idea/other.xml | 22 +- app/build.gradle.kts | 6 +- app/src/main/AndroidManifest.xml | 4 +- .../java/com/hmoa/app/navigation/NavHost.kt | 2 +- .../com/hmoa/core_common/CommonFunctions.kt | 11 +- .../Member/MemberDataStoreImpl.kt | 2 +- .../Survey/SurveyRemoteDataStore.kt | 2 + .../Survey/SurveyRemoteDataStoreImpl.kt | 19 +- .../component/PerfumeItemView.kt | 20 +- .../component/ProgressBar.kt | 11 +- .../core_designsystem/component/TopBar.kt | 4 +- .../entity/data/HbtiQuestionItems.kt | 5 +- .../repository/SurveyRepository.kt | 6 +- .../response/HbtiHomeMetaDataResponse.kt | 11 + .../core_network/service/SurveyService.kt | 3 + .../core_repository/SurveyRepositoryImpl.kt | 9 +- .../hmoa/feature_hbti/screen/HbtiScreen.kt | 201 +++++++------ .../feature_hbti/screen/HbtiSurveyScreen.kt | 45 +-- .../feature_hbti/screen/NotePickScreen.kt | 105 ++++--- .../screen/PerfumeRecommendationScreen.kt | 6 +- .../viewmodel/HbtiHomeViewModel.kt | 237 ++++++++++----- .../viewmodel/HbtiSurveyViewmodel.kt | 9 +- .../viewmodel/NotePickViewmodel.kt | 26 +- .../feature_hbti/NotePickViewmodelTest.kt | 6 +- .../hmoa/feature_home/screen/HomeScreen.kt | 269 +++++++++++++----- .../feature_home/viewmodel/HomeViewModel.kt | 12 +- .../feature_magazine/Screen/MagazineMain.kt | 2 +- .../Screen/EditProfilePage.kt | 2 +- .../feature_userinfo/Screen/MyBirthPage.kt | 2 +- .../feature_userinfo/Screen/MyCommentPage.kt | 2 +- .../Screen/MyFavoriteCommentPage.kt | 2 +- .../Screen/MyFavoritePrefumePage.kt | 4 +- .../feature_userinfo/Screen/MyGenderPage.kt | 2 +- .../hmoa/feature_userinfo/Screen/MyPage.kt | 23 +- .../feature_userinfo/Screen/RefundPage.kt | 2 +- .../feature_userinfo/navigation/NavGraph.kt | 22 +- .../viewModel/MyBirthViewModel.kt | 2 +- .../viewModel/MyGenderViewModel.kt | 44 ++- 40 files changed, 723 insertions(+), 445 deletions(-) create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/HbtiHomeMetaDataResponse.kt diff --git a/.gitignore b/.gitignore index 8049eeb09..765e11f74 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ local.properties deploymentTargetDropDown.xml /config.json +/.idea/other.xml +/.idea/deploymentTargetSelector.xml \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml index 5ac6d449e..9f9d13654 100644 --- a/.idea/deploymentTargetSelector.xml +++ b/.idea/deploymentTargetSelector.xml @@ -4,7 +4,7 @@ - \ 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 @@ diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c3998389c..c38cbc0c2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,4 +1,4 @@ -import java.util.* +import java.util.Properties plugins { id("com.android.application") @@ -22,7 +22,7 @@ android { applicationId = "com.hmoa.app" minSdk = 26 targetSdk = 34 - versionCode = 23 + versionCode = 27 versionName = "1.1.4" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" @@ -133,4 +133,4 @@ dependencies { 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 +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d250ee1f8..cdfe52f31 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -18,7 +18,8 @@ ?): Float { } } -fun OrderStatus.toDisplayString(): String{ - return when(this){ +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 -> "환불 완료" @@ -62,4 +67,4 @@ fun absolutePath(context: Context, uri: Uri): String? { return null } return file.absolutePath -} \ 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 9d8180061..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 @@ -331,4 +331,4 @@ class MemberDataStoreImpl @Inject constructor( } 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 d6525aba0..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 @@ -18,4 +18,6 @@ interface SurveyRemoteDataStore { 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 18fe2964e..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 @@ -149,4 +149,21 @@ class SurveyRemoteDataStoreImpl @Inject constructor( } return result } -} \ No newline at end of file + + 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/src/main/java/com/hmoa/core_designsystem/component/PerfumeItemView.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/PerfumeItemView.kt index 959b92262..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 @@ -3,11 +3,7 @@ package com.hmoa.core_designsystem.component import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.background import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.* import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -33,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 ) { @@ -47,14 +44,17 @@ fun PerfumeItemView( ) } Text( - text = brandName, style = TextStyle(fontSize = 14.sp, fontWeight = FontWeight.Normal, + 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 = CustomFont.regular), + 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/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/TopBar.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/TopBar.kt index 25a43a703..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 @@ -22,7 +22,7 @@ import com.hmoa.core_designsystem.theme.CustomFont @Composable fun TopBar( - color: Color = Color.White, + color: Color = Color.Transparent, iconSize: Dp = 20.dp, //icon 크기 navIcon: Painter? = null, //navigation 버튼 onNavClick: () -> Unit = {}, //navigation click 이벤트 @@ -90,4 +90,4 @@ fun TopBarPreview() { onMenuClick = {}, menuIconColor = CustomColor.gray2 ) -} \ 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 index f700ce367..acaf63dc2 100644 --- 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 @@ -3,5 +3,6 @@ package com.hmoa.core_domain.entity.data typealias QuestionPageIndex = Int data class HbtiQuestionItems( - val hbtiQuestions: MutableMap -) \ No newline at end of file + val hbtiQuestions: MutableMap, + val questionCounts: Int +) diff --git a/core-domain/src/main/java/com/hmoa/core_domain/repository/SurveyRepository.kt b/core-domain/src/main/java/com/hmoa/core_domain/repository/SurveyRepository.kt index c128412b8..ef2c5a12c 100644 --- a/core-domain/src/main/java/com/hmoa/core_domain/repository/SurveyRepository.kt +++ b/core-domain/src/main/java/com/hmoa/core_domain/repository/SurveyRepository.kt @@ -5,10 +5,7 @@ import com.hmoa.core_model.PerfumeRecommendType import com.hmoa.core_model.request.NoteResponseDto import com.hmoa.core_model.request.PerfumeSurveyAnswerRequestDto import com.hmoa.core_model.request.SurveyRespondRequestDto -import com.hmoa.core_model.response.PerfumeRecommendsResponseDto -import com.hmoa.core_model.response.PerfumeSurveyResponseDto -import com.hmoa.core_model.response.RecommendNotesResponseDto -import com.hmoa.core_model.response.SurveyQuestionsResponseDto +import com.hmoa.core_model.response.* interface SurveyRepository { suspend fun getSurveyQuestions(): ResultResponse @@ -32,4 +29,5 @@ interface SurveyRepository { fun savePriceSortedPerfumeRecommendsResult(dto: PerfumeRecommendsResponseDto) fun getPriceSortedPerfumeRecommendsResult(): ResultResponse + suspend fun getHbtiHomeMetaDataResult(): ResultResponse } \ No newline at end of file diff --git a/core-model/src/main/java/com/hmoa/core_model/response/HbtiHomeMetaDataResponse.kt b/core-model/src/main/java/com/hmoa/core_model/response/HbtiHomeMetaDataResponse.kt new file mode 100644 index 000000000..9c67ce192 --- /dev/null +++ b/core-model/src/main/java/com/hmoa/core_model/response/HbtiHomeMetaDataResponse.kt @@ -0,0 +1,11 @@ +package com.hmoa.core_model.response + +import kotlinx.serialization.Serializable + +@Serializable +data class HbtiHomeMetaDataResponse( + val backgroundImgUrl: String, + val firstImageUrl: String, + val isOrdered: Boolean, + val secondImageUrl: String, +) diff --git a/core-network/src/main/java/com/hmoa/core_network/service/SurveyService.kt b/core-network/src/main/java/com/hmoa/core_network/service/SurveyService.kt index 711da98bd..3a6902186 100644 --- a/core-network/src/main/java/com/hmoa/core_network/service/SurveyService.kt +++ b/core-network/src/main/java/com/hmoa/core_network/service/SurveyService.kt @@ -38,4 +38,7 @@ interface SurveyService { @Body dto: PerfumeSurveyAnswerRequestDto, @Query("recommendType") recommendType: String ): ApiResponse + + @GET("/survey/home") + suspend fun getHbtiHomeMetaData(): ApiResponse } \ No newline at end of file diff --git a/core-repository/src/main/java/com/hmoa/core_repository/SurveyRepositoryImpl.kt b/core-repository/src/main/java/com/hmoa/core_repository/SurveyRepositoryImpl.kt index f4b0526e7..e5d15bc59 100644 --- a/core-repository/src/main/java/com/hmoa/core_repository/SurveyRepositoryImpl.kt +++ b/core-repository/src/main/java/com/hmoa/core_repository/SurveyRepositoryImpl.kt @@ -8,10 +8,7 @@ import com.hmoa.core_model.PerfumeRecommendType import com.hmoa.core_model.request.NoteResponseDto import com.hmoa.core_model.request.PerfumeSurveyAnswerRequestDto import com.hmoa.core_model.request.SurveyRespondRequestDto -import com.hmoa.core_model.response.PerfumeRecommendsResponseDto -import com.hmoa.core_model.response.PerfumeSurveyResponseDto -import com.hmoa.core_model.response.RecommendNotesResponseDto -import com.hmoa.core_model.response.SurveyQuestionsResponseDto +import com.hmoa.core_model.response.* import javax.inject.Inject class SurveyRepositoryImpl @Inject constructor( @@ -72,4 +69,8 @@ class SurveyRepositoryImpl @Inject constructor( override fun getPriceSortedPerfumeRecommendsResult(): ResultResponse { return surveyLocalDataStore.getPriceSortedPerfumeRecommendsResult() } + + override suspend fun getHbtiHomeMetaDataResult(): ResultResponse { + return surveyRemoteDataStore.getHbtiHomeMetaDataResult() + } } \ No newline at end of file diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiScreen.kt index 0a00e67ba..84b4b2a49 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiScreen.kt @@ -3,17 +3,7 @@ package com.hmoa.feature_hbti.screen import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable -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.aspectRatio -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.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape @@ -22,17 +12,13 @@ import androidx.compose.material.ModalBottomSheetLayout import androidx.compose.material.ModalBottomSheetValue import androidx.compose.material3.Text import androidx.compose.material3.TextButton -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.runtime.setValue +import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight @@ -42,16 +28,11 @@ import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.hmoa.core_common.ErrorUiState -import com.hmoa.core_designsystem.component.AppLoadingScreen -import com.hmoa.core_designsystem.component.EditModal -import com.hmoa.core_designsystem.component.ErrorUiSetView -import com.hmoa.core_designsystem.component.ImageView -import com.hmoa.core_designsystem.component.ReportModal -import com.hmoa.core_designsystem.component.ReviewItem -import com.hmoa.core_designsystem.component.TopBar +import com.hmoa.core_designsystem.component.* import com.hmoa.core_designsystem.theme.CustomColor import com.hmoa.core_designsystem.theme.pretendard import com.hmoa.core_domain.entity.navigation.HbtiRoute +import com.hmoa.core_model.response.HbtiHomeMetaDataResponse import com.hmoa.core_model.response.Photo import com.hmoa.core_model.response.ReviewResponseDto import com.hmoa.feature_hbti.viewmodel.HbtiHomeUiState @@ -71,17 +52,20 @@ fun HbtiRoute( ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() val errState by viewModel.errorUiState.collectAsStateWithLifecycle() + val isOrderWarninngNeeded by viewModel.isOrderedWarningNeedState.collectAsStateWithLifecycle() HbtiScreen( onHbtiSurveyClick = { onHbtiSurveyClick() }, - onAfterOrderClick = { onAfterOrderClick() }, + onAfterOrderClick = { viewModel::onAfterOrderClick { onAfterOrderClick() } }, navHome = navHome, navReview = { navReview(HbtiRoute.Hbti) }, navBack = navBack, navEditReview = navEditReview, onDeleteClick = viewModel::deleteReview, onReportClick = viewModel::reportReview, + onAfterOrderWarningDialogClick = viewModel::initializeIsOrderWarningNeedState, uiState = uiState, errState = errState, + isOrderWarningNeed = isOrderWarninngNeeded, onHeartClick = viewModel::onHeartClick, navLogin = navLogin ) @@ -90,7 +74,6 @@ fun HbtiRoute( @Composable fun HbtiScreen( onHbtiSurveyClick: () -> Unit, - onAfterOrderClick: () -> Unit, navBack: () -> Unit, navHome: () -> Unit, navLogin: () -> Unit, @@ -98,23 +81,30 @@ fun HbtiScreen( navEditReview: (reviewId: Int) -> Unit, onDeleteClick: (reviewId: Int) -> Unit, onReportClick: (reviewId: Int) -> Unit, + onAfterOrderClick: () -> Unit, + onAfterOrderWarningDialogClick: () -> Unit, uiState: HbtiHomeUiState, + isOrderWarningNeed: Boolean, errState: ErrorUiState, onHeartClick: (reviewId: Int, isLiked: Boolean) -> Unit, ) { + ErrorUiSetView( + onLoginClick = navLogin, + errorUiState = errState, + onCloseClick = navHome + ) + + OrderWarningDialog(isOrderWarnNeeded = isOrderWarningNeed, onAfterClick = onAfterOrderWarningDialogClick) + when (uiState) { HbtiHomeUiState.Loading -> AppLoadingScreen() HbtiHomeUiState.Error -> { - ErrorUiSetView( - onLoginClick = navLogin, - errorUiState = errState, - onCloseClick = navHome - ) } is HbtiHomeUiState.Success -> { HbtiHomeContent( reviews = uiState.reviews, + metadata = uiState.metadata, onHbtiSurveyClick = onHbtiSurveyClick, onAfterOrderClick = onAfterOrderClick, onReviewItemClick = navReview, @@ -128,10 +118,30 @@ fun HbtiScreen( } } +@Composable +private fun OrderWarningDialog(isOrderWarnNeeded: Boolean, onAfterClick: () -> Unit) { + val screenWidth = LocalConfiguration.current.screenWidthDp.dp + AppDesignDialog( + isOpen = isOrderWarnNeeded, + modifier = Modifier.wrapContentHeight() + .width(screenWidth - 88.dp), + title = "주문 후 이용가능한 서비스입니다", + content = "배송 후 후기를 작성해주세요", + buttonTitle = "확인", + onOkClick = { + onAfterClick() + }, + onCloseClick = { + onAfterClick() + } + ) +} + @OptIn(ExperimentalMaterialApi::class) @Composable private fun HbtiHomeContent( reviews: List, + metadata: HbtiHomeMetaDataResponse?, onHbtiSurveyClick: () -> Unit, onAfterOrderClick: () -> Unit, onReviewItemClick: () -> Unit, @@ -239,7 +249,7 @@ private fun HbtiHomeContent( shape = RoundedCornerShape(5.dp) )) { ImageView( - imageUrl = "https://github.com/HMOAA/HMOA_ANDROID/assets/67788699/122bc5b1-1cc1-44b3-a468-1b56f9998994", + imageUrl = metadata?.firstImageUrl, width = 1f, height = 1f, backgroundColor = Color.Transparent, @@ -277,7 +287,7 @@ private fun HbtiHomeContent( ) ) { ImageView( - imageUrl = "https://github.com/HMOAA/HMOA_ANDROID/assets/67788699/4bb30703-d77d-49ac-8a01-2aee48bf04c3", + imageUrl = metadata?.secondImageUrl, width = 1f, height = 1f, backgroundColor = Color.Transparent, @@ -380,77 +390,82 @@ private fun HbtiHomeContent( @Preview @Composable fun HbtiScreenPreview() { - HbtiScreen({}, {}, errState = ErrorUiState.Loading, uiState = HbtiHomeUiState.Success( - listOf( - ReviewResponseDto( - hbtiReviewId = 0, - profileImgUrl = "", - author = "향수 러버", - content = "향수를 1회도 구매하지 않은 사람인데 향모아에서 인생향수 찾았어요!", - imagesCount = 4, - hbtiPhotos = listOf( - Photo( - photoUrl = "", - photoId = 0 - ), - Photo( - photoUrl = "", - photoId = 0 - ), - Photo( - photoUrl = "", - photoId = 0 - ), - Photo( - photoUrl = "", - photoId = 0 + HbtiScreen( + {}, errState = ErrorUiState.Loading, uiState = HbtiHomeUiState.Success( + listOf( + ReviewResponseDto( + hbtiReviewId = 0, + profileImgUrl = "", + author = "향수 러버", + content = "향수를 1회도 구매하지 않은 사람인데 향모아에서 인생향수 찾았어요!", + imagesCount = 4, + hbtiPhotos = listOf( + Photo( + photoUrl = "", + photoId = 0 + ), + Photo( + photoUrl = "", + photoId = 0 + ), + Photo( + photoUrl = "", + photoId = 0 + ), + Photo( + photoUrl = "", + photoId = 0 + ), ), + createdAt = "10일 전", + isWrited = false, + heartCount = 12, + isLiked = false, + orderTitle = "시트러스" ), - createdAt = "10일 전", - isWrited = false, - heartCount = 12, - isLiked = false, - orderTitle = "시트러스" - ), - ReviewResponseDto( - hbtiReviewId = 0, - profileImgUrl = "", - author = "향수 러버", - content = "평소에 선호하는 향이 있었는데 그 향의 이름을 몰랐는데 향료 배송받고 시향해본 통카 빈? 이더라구요 제가 좋아했던 향수들은 다 통카 빈이 들어가있네요 ㅎ 저 같은 분들에게 추천해요", - imagesCount = 4, - hbtiPhotos = listOf( - Photo( - photoUrl = "", - photoId = 0 - ), - Photo( - photoUrl = "", - photoId = 0 - ), - Photo( - photoUrl = "", - photoId = 0 - ), - Photo( - photoUrl = "", - photoId = 0 + ReviewResponseDto( + hbtiReviewId = 0, + profileImgUrl = "", + author = "향수 러버", + content = "평소에 선호하는 향이 있었는데 그 향의 이름을 몰랐는데 향료 배송받고 시향해본 통카 빈? 이더라구요 제가 좋아했던 향수들은 다 통카 빈이 들어가있네요 ㅎ 저 같은 분들에게 추천해요", + imagesCount = 4, + hbtiPhotos = listOf( + Photo( + photoUrl = "", + photoId = 0 + ), + Photo( + photoUrl = "", + photoId = 0 + ), + Photo( + photoUrl = "", + photoId = 0 + ), + Photo( + photoUrl = "", + photoId = 0 + ), ), + createdAt = "10일 전", + isWrited = false, + heartCount = 12, + isLiked = true, + orderTitle = "시트러스" ), - createdAt = "10일 전", - isWrited = false, - heartCount = 12, - isLiked = true, - orderTitle = "시트러스" ), - ) - ), + null + ), navBack = {}, navHome = {}, navReview = {}, onHeartClick = { a, b -> }, onReportClick = {}, onDeleteClick = {}, + onAfterOrderClick = {}, + onAfterOrderWarningDialogClick = {}, navEditReview = {}, - navLogin = {} + navLogin = {}, + isOrderWarningNeed = false ) } diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt index 8f76a772d..f9fa85495 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt @@ -20,7 +20,7 @@ import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.hmoa.core_common.ErrorUiState -import com.hmoa.core_common.calculateProgressStepSize +import com.hmoa.core_common.calculateHbtiProgressStepSize import com.hmoa.core_designsystem.component.* import com.hmoa.core_designsystem.theme.CustomColor import com.hmoa.core_designsystem.theme.CustomFont @@ -112,15 +112,13 @@ fun HbtiSurveyContent( var currentProgress by remember { mutableStateOf(0f) } var targetProgress by remember { mutableStateOf(0f) } val scope = rememberCoroutineScope() // Create a coroutine scope - val pageContent = hbtiQuestionItems?.hbtiQuestions?.values?.map { it } - val additionalProgress = calculateProgressStepSize(pageContent) val pagerState = - rememberPagerState(initialPage = 0, pageCount = { hbtiQuestionItems?.hbtiQuestions?.values?.size ?: 0 }) - + rememberPagerState(initialPage = 0, pageCount = { hbtiQuestionItems?.questionCounts ?: 0 }) + val additionalProgress = calculateHbtiProgressStepSize(hbtiQuestionItems?.questionCounts ?: 13) fun addProgress() { targetProgress += additionalProgress scope.launch { - loadProgress { progress -> + loadProgress(additionalProgress) { progress -> if (currentProgress <= targetProgress) { currentProgress += progress } @@ -131,7 +129,7 @@ fun HbtiSurveyContent( fun subtractProgress() { targetProgress -= additionalProgress scope.launch { - loadProgress { progress -> + loadProgress(additionalProgress) { progress -> if (currentProgress >= targetProgress) { currentProgress -= progress } @@ -139,19 +137,31 @@ fun HbtiSurveyContent( } } + fun preventScrollOver2Pages(currentPage: Int, targetPage: Int) { + if (kotlin.math.abs(targetPage - currentPage) > 1) { + scope.launch { pagerState.animateScrollToPage(currentPage) } + } + } + + LaunchedEffect(pagerState) { + snapshotFlow { pagerState.targetPage } + .collect { targetPage -> + val currentPage = pagerState.currentPage + preventScrollOver2Pages(currentPage, targetPage) + if (currentPage > targetPage) { + subtractProgress() + } else if (currentPage < targetPage) { + addProgress() + } + } + } + Column(modifier = Modifier.fillMaxSize().background(color = Color.White)) { TopBar( title = "향BTI", titleColor = Color.Black, navIcon = painterResource(com.hmoa.core_designsystem.R.drawable.ic_back), - onNavClick = { - if (pagerState.currentPage == 0) { - onBackClick() - } else { - subtractProgress() - scope.launch { pagerState.animateScrollToPage(pagerState.currentPage - 1) } - } - } + onNavClick = onBackClick ) Column( modifier = Modifier.padding(horizontal = 16.dp).padding(bottom = 40.dp).fillMaxHeight(1f), @@ -166,10 +176,10 @@ fun HbtiSurveyContent( Column { ProgressBar(percentage = currentProgress) HorizontalPager( - userScrollEnabled = false, + userScrollEnabled = isNextQuestionAvailable?.get(pagerState.currentPage) ?: true, modifier = Modifier.fillMaxWidth().background(color = Color.White), state = pagerState, - verticalAlignment = Alignment.Top + verticalAlignment = Alignment.Top, ) { page -> Column(verticalArrangement = Arrangement.SpaceBetween) { Column(modifier = Modifier.fillMaxWidth()) { @@ -208,7 +218,6 @@ fun HbtiSurveyContent( isEnabled = isNextQuestionAvailable?.get(pagerState.currentPage) ?: true, btnText = "다음", onClick = { - addProgress() scope.launch { pagerState.animateScrollToPage(pagerState.currentPage + 1) } diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt index ba79240f0..d948b891b 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.layout.ContentScale 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.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel @@ -120,13 +121,36 @@ fun NoteContent( ) { Text( "추천받은 카테고리는 '${topRecommendedNote}'입니다.\n그 외에 원하는 시향카드 카테고리를\n선택해주세요", - modifier = Modifier.padding(bottom = 32.dp, top = 36.dp), + modifier = Modifier.padding(bottom = 12.dp, top = 36.dp), style = TextStyle( fontSize = 20.sp, fontWeight = FontWeight.SemiBold, fontFamily = pretendard ) ) + Row { + Text( + "*", + modifier = Modifier.padding(bottom = 28.dp), + style = TextStyle( + color = CustomColor.gray5, + fontSize = 9.sp, + fontWeight = FontWeight.Medium, + fontFamily = pretendard + ), + textAlign = TextAlign.Start + ) + Text( + "향료 1개당 900원", + modifier = Modifier.padding(bottom = 28.dp), + style = TextStyle( + color = CustomColor.gray5, + fontSize = 14.sp, + fontWeight = FontWeight.Medium, + fontFamily = pretendard + ) + ) + } NotePickGridWindow( notes = noteList, isNoteSelectedList = isNoteSelectedList, @@ -154,46 +178,47 @@ fun NotePickGridWindow( isNoteSelectedList: List, onClickItem: (index: Int, value: Boolean, data: NoteSelect) -> Unit ) { - if (notes?.data == null) { - Text("데이터가 없습니다") - } else { - LazyVerticalGrid(columns = GridCells.Fixed(3), verticalArrangement = Arrangement.SpaceBetween) { - itemsIndexed(notes?.data ?: emptyList()) { index, item -> - Column( - modifier = Modifier.padding(vertical = 10.dp).padding(horizontal = 5.dp), - horizontalAlignment = Alignment.CenterHorizontally - ) { - NoteImageView( - imageUrl = item.productPhotoUrl, - width = 74f, - height = 74f, - backgroundColor = Color.Transparent, - contentScale = ContentScale.Crop, - onClicked = { - onClickItem( - index, - !isNoteSelectedList[index].isSelected, - isNoteSelectedList[index] - ) - }, - isRecommanded = item.isRecommended, - index = isNoteSelectedList[index].nodeFaceIndex, - isSelected = isNoteSelectedList[index].isSelected - ) - Text( - text = item.productName, - style = TextStyle(fontFamily = pretendard, fontWeight = FontWeight.SemiBold, fontSize = 14.sp), - modifier = Modifier.padding(top = 12.dp, bottom = 5.dp) - ) - Text( - text = item.productDetails, - style = TextStyle(fontFamily = pretendard, fontWeight = FontWeight.Normal, fontSize = 12.sp) - ) - Text( - text = "(총 ${item.price}원)", - style = TextStyle(fontFamily = pretendard, fontWeight = FontWeight.Normal, fontSize = 12.sp) + LazyVerticalGrid(columns = GridCells.Fixed(3), verticalArrangement = Arrangement.SpaceBetween) { + itemsIndexed(notes?.data ?: emptyList()) { index, item -> + Column( + modifier = Modifier.padding(vertical = 10.dp).padding(horizontal = 5.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + NoteImageView( + imageUrl = item.productPhotoUrl, + width = 74f, + height = 74f, + backgroundColor = Color.Transparent, + contentScale = ContentScale.Crop, + onClicked = { + onClickItem( + index, + !isNoteSelectedList.get(index).isSelected, + isNoteSelectedList.get(index) + ) + }, + isRecommanded = item.isRecommended, + index = isNoteSelectedList.get(index).nodeFaceIndex, + isSelected = isNoteSelectedList.get(index).isSelected + ) + Text( + text = item.productName, + style = TextStyle(fontFamily = pretendard, fontWeight = FontWeight.SemiBold, fontSize = 14.sp), + modifier = Modifier.padding(top = 12.dp, bottom = 5.dp) + ) + Text( + text = item.productDetails, + style = TextStyle( + fontFamily = pretendard, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + textAlign = TextAlign.Center ) - } + ) + Text( + text = "(총 ${item.price}원)", + style = TextStyle(fontFamily = pretendard, fontWeight = FontWeight.Normal, fontSize = 12.sp) + ) } } } diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/PerfumeRecommendationScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/PerfumeRecommendationScreen.kt index bbece9b55..993c52b1e 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/PerfumeRecommendationScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/PerfumeRecommendationScreen.kt @@ -121,7 +121,7 @@ fun PerfumeRecommendationScreen( fun addProgress() { targetProgress += additionalProgress scope.launch { - loadProgress { progress -> + loadProgress(additionalProgress) { progress -> if (currentProgress <= targetProgress) { currentProgress += progress } @@ -132,7 +132,7 @@ fun PerfumeRecommendationScreen( fun subtractProgress() { targetProgress -= additionalProgress scope.launch { - loadProgress { progress -> + loadProgress(additionalProgress) { progress -> if (currentProgress >= targetProgress) { currentProgress -= progress } @@ -358,4 +358,4 @@ private fun NoteScreen( @Preview @Composable private fun PreviewScreen() { -} \ No newline at end of file +} diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiHomeViewModel.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiHomeViewModel.kt index 8ec9a1eef..6a417e13e 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiHomeViewModel.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiHomeViewModel.kt @@ -1,23 +1,18 @@ package com.hmoa.feature_hbti.viewmodel +import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.hmoa.core_common.ErrorMessageType -import com.hmoa.core_common.ErrorUiState -import com.hmoa.core_common.Result -import com.hmoa.core_common.asResult -import com.hmoa.core_common.handleErrorType +import com.hmoa.core_common.* import com.hmoa.core_domain.repository.HShopReviewRepository +import com.hmoa.core_domain.repository.LoginRepository import com.hmoa.core_domain.repository.ReportRepository +import com.hmoa.core_domain.repository.SurveyRepository +import com.hmoa.core_model.response.HbtiHomeMetaDataResponse import com.hmoa.core_model.response.ReviewResponseDto import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.stateIn -import kotlinx.coroutines.flow.update +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import javax.inject.Inject @@ -25,9 +20,15 @@ import javax.inject.Inject class HbtiHomeViewModel @Inject constructor( private val hShopReviewRepository: HShopReviewRepository, private val reportRepository: ReportRepository, -): ViewModel() { + private val surveyRepository: SurveyRepository, + private val loginRepository: LoginRepository +) : ViewModel() { private val flag = MutableStateFlow(false) + private val reviewsState = MutableStateFlow>(listOf()) + private val metadataState = MutableStateFlow(null) + private val _isOrderedWarningNeedState = MutableStateFlow(false) + val isOrderedWarningNeedState: StateFlow = _isOrderedWarningNeedState private var expiredTokenErrorState = MutableStateFlow(false) private var wrongTypeTokenErrorState = MutableStateFlow(false) private var unLoginedErrorState = MutableStateFlow(false) @@ -50,84 +51,182 @@ class HbtiHomeViewModel @Inject constructor( initialValue = ErrorUiState.Loading ) - val uiState = flag.map{ - val response = hShopReviewRepository.getReviews(0) - if (response.errorMessage != null){ - throw Exception(response.errorMessage!!.message) + val uiState: StateFlow = + combine(reviewsState, metadataState) { _reviews, _metadata -> + HbtiHomeUiState.Success( + reviews = _reviews, + metadata = _metadata, + ) + }.stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5_000), + initialValue = HbtiHomeUiState.Loading + ) + + init { + getMetaData() + getReviews() + checkIsLogined() + } + + fun checkIsLogined() { + viewModelScope.launch(Dispatchers.IO) { + loginRepository.getAuthToken().collectLatest { + if (it == null) { + unLoginedErrorState.update { true } + } + } } - response.data - }.asResult().map{ result -> - when(result){ - Result.Loading -> HbtiHomeUiState.Loading - is Result.Success -> { - val data = if(result.data!!.data.size > 5) result.data!!.data.subList(0,5) else result.data!!.data - HbtiHomeUiState.Success(data) + } + + fun getMetaData() { + viewModelScope.launch(Dispatchers.IO) { + flow { + val response = surveyRepository.getHbtiHomeMetaDataResult() + response.emitOrThrow { emit(it) } + }.asResult().collectLatest { result -> + when (result) { + Result.Loading -> HbtiHomeUiState.Loading + is Result.Success -> { + Log.d("HbtiHomeViewMdoel", "data:${result.data.data}") + metadataState.update { result.data.data } + } + + is Result.Error -> { + handleErrorType( + error = result.exception, + onExpiredTokenError = { expiredTokenErrorState.update { true } }, + onUnknownError = { unLoginedErrorState.update { true } }, + onWrongTypeTokenError = { wrongTypeTokenErrorState.update { true } }, + onGeneralError = { generalErrorState.update { Pair(true, result.exception.message) } } + ) + HbtiHomeUiState.Error + } + } } - is Result.Error -> { - handleErrorType( - error = result.exception, - onExpiredTokenError = {expiredTokenErrorState.update{true}}, - onUnknownError = {unLoginedErrorState.update{true}}, - onWrongTypeTokenError = {wrongTypeTokenErrorState.update{true}}, - onGeneralError = {generalErrorState.update{Pair(true, result.exception.message)}} - ) - HbtiHomeUiState.Error + } + } + + fun getReviews() { + viewModelScope.launch(Dispatchers.IO) { + flow { + val response = hShopReviewRepository.getReviews(0) + response.emitOrThrow { emit(it) } + }.asResult().collectLatest { result -> + when (result) { + Result.Loading -> HbtiHomeUiState.Loading + is Result.Success -> { + val data = result.data.data?.data + if (data != null) { + if (data.size > 5) data.subList(0, 5) else data + reviewsState.update { data } + } + } + + is Result.Error -> { + handleErrorType( + error = result.exception, + onExpiredTokenError = { expiredTokenErrorState.update { true } }, + onUnknownError = { unLoginedErrorState.update { true } }, + onWrongTypeTokenError = { wrongTypeTokenErrorState.update { true } }, + onGeneralError = { generalErrorState.update { Pair(true, result.exception.message) } } + ) + HbtiHomeUiState.Error + } + } } } - }.stateIn( - scope = viewModelScope, - started = SharingStarted.WhileSubscribed(5_000), - initialValue = HbtiHomeUiState.Loading - ) + } - fun onHeartClick(reviewId: Int, isLiked: Boolean){ - viewModelScope.launch{ - val result = if (isLiked) hShopReviewRepository.deleteReviewLike(reviewId) else hShopReviewRepository.putReviewLike(reviewId) - if(result.errorMessage != null){ - when(result.errorMessage!!.message){ - ErrorMessageType.UNKNOWN_ERROR.name -> unLoginedErrorState.update{true} - ErrorMessageType.WRONG_TYPE_TOKEN.name -> wrongTypeTokenErrorState.update{true} - ErrorMessageType.EXPIRED_TOKEN.name -> expiredTokenErrorState.update{true} - else -> generalErrorState.update{Pair(true, result.errorMessage!!.message)} + fun onHeartClick(reviewId: Int, isLiked: Boolean) { + viewModelScope.launch { + val result = + if (isLiked) hShopReviewRepository.deleteReviewLike(reviewId) else hShopReviewRepository.putReviewLike( + reviewId + ) + if (result.errorMessage != null) { + when (result.errorMessage!!.message) { + ErrorMessageType.UNKNOWN_ERROR.name -> unLoginedErrorState.update { true } + ErrorMessageType.WRONG_TYPE_TOKEN.name -> wrongTypeTokenErrorState.update { true } + ErrorMessageType.EXPIRED_TOKEN.name -> expiredTokenErrorState.update { true } + else -> generalErrorState.update { Pair(true, result.errorMessage!!.message) } } } } } - fun reportReview(reviewId: Int){ - viewModelScope.launch{ + + fun onAfterOrderClick(onAvailable: () -> Unit) { + Log.d("HbtiHomeViewModel", "isOrderedWarningNeedState.value: ${isOrderedWarningNeedState.value}") + if (metadataState.value?.isOrdered ?: true) { + onAvailable() + } else { + _isOrderedWarningNeedState.update { true } + } + } + + fun initializeIsOrderWarningNeedState() { + _isOrderedWarningNeedState.update { false } + Log.d("HbtiHomeViewModel", "isOrderedWarningNeedState.value: ${isOrderedWarningNeedState.value}") + } + + fun reportReview(reviewId: Int) { + viewModelScope.launch { val result = reportRepository.reportReview(reviewId) - if (result.errorMessage != null){ - when(result.errorMessage!!.message){ - ErrorMessageType.UNKNOWN_ERROR.name -> {unLoginedErrorState.update{true}} - ErrorMessageType.WRONG_TYPE_TOKEN.name -> {wrongTypeTokenErrorState.update{true}} - ErrorMessageType.EXPIRED_TOKEN.name -> {expiredTokenErrorState.update{true}} - else -> {generalErrorState.update{Pair(true, result.errorMessage!!.message)}} + if (result.errorMessage != null) { + when (result.errorMessage!!.message) { + ErrorMessageType.UNKNOWN_ERROR.name -> { + unLoginedErrorState.update { true } + } + + ErrorMessageType.WRONG_TYPE_TOKEN.name -> { + wrongTypeTokenErrorState.update { true } + } + + ErrorMessageType.EXPIRED_TOKEN.name -> { + expiredTokenErrorState.update { true } + } + + else -> { + generalErrorState.update { Pair(true, result.errorMessage!!.message) } + } } } } } - fun deleteReview(reviewId: Int){ - viewModelScope.launch{ + fun deleteReview(reviewId: Int) { + viewModelScope.launch { val result = hShopReviewRepository.deleteReview(reviewId) - if(result.errorMessage != null){ - when(result.errorMessage!!.message){ - ErrorMessageType.UNKNOWN_ERROR.name -> {unLoginedErrorState.update{true}} - ErrorMessageType.WRONG_TYPE_TOKEN.name -> {wrongTypeTokenErrorState.update{true}} - ErrorMessageType.EXPIRED_TOKEN.name -> {expiredTokenErrorState.update{true}} - else -> {generalErrorState.update{Pair(true, result.errorMessage!!.message)}} + if (result.errorMessage != null) { + when (result.errorMessage!!.message) { + ErrorMessageType.UNKNOWN_ERROR.name -> { + unLoginedErrorState.update { true } + } + + ErrorMessageType.WRONG_TYPE_TOKEN.name -> { + wrongTypeTokenErrorState.update { true } + } + + ErrorMessageType.EXPIRED_TOKEN.name -> { + expiredTokenErrorState.update { true } + } + + else -> { + generalErrorState.update { Pair(true, result.errorMessage!!.message) } + } } return@launch } - flag.update{!flag.value} + flag.update { !flag.value } } } } -sealed interface HbtiHomeUiState{ - data object Error: HbtiHomeUiState - data object Loading: HbtiHomeUiState +sealed interface HbtiHomeUiState { + data object Error : HbtiHomeUiState + data object Loading : HbtiHomeUiState data class Success( - val reviews: List - ): HbtiHomeUiState + val reviews: List, + val metadata: HbtiHomeMetaDataResponse? + ) : HbtiHomeUiState } \ No newline at end of file diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiSurveyViewmodel.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiSurveyViewmodel.kt index fc518a86f..21ee75fb9 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiSurveyViewmodel.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiSurveyViewmodel.kt @@ -3,9 +3,9 @@ package com.hmoa.feature_hbti.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.hmoa.core_common.* -import com.hmoa.core_domain.repository.SurveyRepository import com.hmoa.core_domain.entity.data.HbtiQuestionItem import com.hmoa.core_domain.entity.data.HbtiQuestionItems +import com.hmoa.core_domain.repository.SurveyRepository import com.hmoa.core_model.request.NoteResponseDto import com.hmoa.core_model.request.SurveyRespondRequestDto import com.hmoa.core_model.response.SurveyQuestionsResponseDto @@ -127,7 +127,8 @@ class HbtiSurveyViewmodel @Inject constructor( HbtiQuestionItems( hbtiQuestions = initializeHbtiQuestionItemsState( result.data.data - ) + ), + questionCounts = result.data.data?.questions?.size ?: 0 ) } _hbtiAnwserIdsState.update { initializeHbtiAnswerIdsState(result.data.data) } @@ -230,11 +231,13 @@ class HbtiSurveyViewmodel @Inject constructor( fun getUpdatedHbtiQuestionItems(page: Int, newHbtiQuestionItem: HbtiQuestionItem): HbtiQuestionItems { val newHbtiQuestionItems = mutableMapOf() + var count = 0 _hbtiQuestionItemsState.value?.hbtiQuestions?.set(page, newHbtiQuestionItem) _hbtiQuestionItemsState.value?.hbtiQuestions?.map { newHbtiQuestionItems[it.key] = it.value + count += 1 } - return HbtiQuestionItems(hbtiQuestions = newHbtiQuestionItems) + return HbtiQuestionItems(hbtiQuestions = newHbtiQuestionItems, questionCounts = count) } fun updatedIsNextQuestionAvailable( diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/NotePickViewmodel.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/NotePickViewmodel.kt index 431c0cb5e..184b11479 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/NotePickViewmodel.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/NotePickViewmodel.kt @@ -21,11 +21,11 @@ class NotePickViewmodel @Inject constructor( ) : ViewModel() { private var _topRecommendedNoteState = MutableStateFlow("") private var _noteProductsState = MutableStateFlow(null) - private var _noteSelectDataState = MutableStateFlow>(listOf()) + private var _isNoteSelectDataState = MutableStateFlow>(listOf()) private var _isNextButtonAvailableState = MutableStateFlow(false) val topRecommendedNoteState: StateFlow = _topRecommendedNoteState val noteProductState: StateFlow = _noteProductsState - val noteSelectDataState: StateFlow> = _noteSelectDataState + val isNoteSelectDataState: StateFlow> = _isNoteSelectDataState val isNextButtonAvailableState: StateFlow = _isNextButtonAvailableState val selectedIds = MutableStateFlow>(emptyList()) private var _noteOrderIndex = MutableStateFlow(1) @@ -38,7 +38,7 @@ class NotePickViewmodel @Inject constructor( combine( _topRecommendedNoteState, _noteProductsState, - _noteSelectDataState, + _isNoteSelectDataState, _noteOrderIndex ) { topRecommendedNote, notes, noteSelectData, noteOrderIndex -> NotePickUiState.NotePickData( @@ -73,12 +73,11 @@ class NotePickViewmodel @Inject constructor( init { viewModelScope.launch(Dispatchers.IO) { getTopRecommendedNote() - launch { getNoteProducts() }.join() - initializeIsNoteSelectedList(_noteProductsState.value) + getNoteProducts() } } - fun initializeIsNoteSelectedList(noteList: ProductListResponseDto?) { + fun initializeIsNoteSelectedList(noteList: ProductListResponseDto?, onUpdateProducts: () -> Unit) { var initializedList = MutableList(noteList?.data?.size ?: 0) { NoteSelect( @@ -99,7 +98,8 @@ class NotePickViewmodel @Inject constructor( ) ) } - _noteSelectDataState.update { initializedList } + _isNoteSelectDataState.update { initializedList } + onUpdateProducts() } suspend fun getTopRecommendedNote() { @@ -115,7 +115,9 @@ class NotePickViewmodel @Inject constructor( when (result) { is com.hmoa.core_common.Result.Success -> { viewModelScope.launch(Dispatchers.IO) { - _noteProductsState.update { result.data.data } + initializeIsNoteSelectedList( + result.data.data, + onUpdateProducts = { _noteProductsState.update { result.data.data } }) } } @@ -137,7 +139,7 @@ class NotePickViewmodel @Inject constructor( } fun postNoteSelected(onSuccess: () -> Unit) { - val requestDto = _noteSelectDataState.value.filter { it.isSelected }.map { it.productId } + val requestDto = _isNoteSelectDataState.value.filter { it.isSelected }.map { it.productId } selectedIds.update { requestDto } viewModelScope.launch(Dispatchers.IO) { flow { @@ -171,10 +173,10 @@ class NotePickViewmodel @Inject constructor( value: Boolean, data: NoteSelect, ) { - var noteSelectData = makeDeepCopyOfNoteSelectData(_noteSelectDataState.value) + var noteSelectData = makeDeepCopyOfNoteSelectData(_isNoteSelectDataState.value) noteSelectData = changeNoteSelectData(index, value, data, noteSelectData) noteSelectData = reorderNoteFaceIndex(noteSelectData) - _noteSelectDataState.update { noteSelectData } + _isNoteSelectDataState.update { noteSelectData } _noteOrderIndex.update { countSelectedNote(noteSelectData) } handleIsNextButtonAvailableState(noteSelectData = noteSelectData) } @@ -266,4 +268,4 @@ sealed interface NotePickUiState { val noteSelectData: List, val noteOrderIndex: Int, ) : NotePickUiState -} \ No newline at end of file +} diff --git a/feature-hbti/src/test/java/com/hmoa/feature_hbti/NotePickViewmodelTest.kt b/feature-hbti/src/test/java/com/hmoa/feature_hbti/NotePickViewmodelTest.kt index 6fef77990..e211296cb 100644 --- a/feature-hbti/src/test/java/com/hmoa/feature_hbti/NotePickViewmodelTest.kt +++ b/feature-hbti/src/test/java/com/hmoa/feature_hbti/NotePickViewmodelTest.kt @@ -144,7 +144,7 @@ class NotePickViewmodelTest : TestCase() { } launch { viewmodel.getNoteProducts() }.join() launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value) }.join() - Assert.assertEquals(expectedNoteSelectData, viewmodel.noteSelectDataState.value) + Assert.assertEquals(expectedNoteSelectData, viewmodel.isNoteSelectDataState.value) } @Test @@ -177,7 +177,7 @@ class NotePickViewmodelTest : TestCase() { isRecommended = targetNode.isRecommended, nodeFaceIndex = null ) - Assert.assertEquals(expectedNoteSelectData, viewmodel.noteSelectDataState.value) + Assert.assertEquals(expectedNoteSelectData, viewmodel.isNoteSelectDataState.value) } @Test @@ -316,4 +316,4 @@ class NotePickViewmodelTest : TestCase() { //Then: 버튼의 사용가능여부 = false이다 Assert.assertEquals(false, viewmodel.isNextButtonAvailableState.value) } -} \ No newline at end of file +} diff --git a/feature-home/src/main/java/com/hmoa/feature_home/screen/HomeScreen.kt b/feature-home/src/main/java/com/hmoa/feature_home/screen/HomeScreen.kt index 1afe6b6e5..79dc85692 100644 --- a/feature-home/src/main/java/com/hmoa/feature_home/screen/HomeScreen.kt +++ b/feature-home/src/main/java/com/hmoa/feature_home/screen/HomeScreen.kt @@ -1,11 +1,15 @@ package com.hmoa.feature_home.screen -import androidx.compose.foundation.* +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.lazy.LazyRow -import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.* +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -25,6 +29,7 @@ import com.hmoa.core_designsystem.component.ImageView import com.hmoa.core_designsystem.component.PerfumeItemView import com.hmoa.core_designsystem.theme.CustomColor import com.hmoa.core_designsystem.theme.CustomFont +import com.hmoa.core_designsystem.theme.pretendard import com.hmoa.core_domain.entity.data.AllPerfumeScreenId import com.hmoa.core_model.response.HomeMenuDefaultResponseDto import com.hmoa.core_model.response.HomeMenuPerfumeResponseDto @@ -51,100 +56,220 @@ private fun HomeScreen( ) { val firstMenuWithBannerState by viewModel.firstMenuWithBannerState.collectAsStateWithLifecycle() val bottomMenuState by viewModel.bottomMenuState.collectAsStateWithLifecycle() - val verticalScrollState = rememberScrollState() - - Column( + val listState = rememberLazyListState() + LaunchedEffect(true) { + listState.animateScrollToItem(index = 0) + } + LazyColumn( modifier = Modifier .fillMaxSize() - .verticalScroll(state = verticalScrollState, reverseScrolling = true) .background(Color.White), + horizontalAlignment = Alignment.CenterHorizontally, + state = listState ) { - when (firstMenuWithBannerState) { - is HomeViewModel.BannerWithFirstMenuState.Loading -> { - AppLoadingScreen() - } - is HomeViewModel.BannerWithFirstMenuState.Data -> { - Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxWidth()) { - FirstMenuWithBannerContent( - onPerfumeClick = { onPerfumeClick(it) }, - bannerImgUrl = (firstMenuWithBannerState as HomeViewModel.BannerWithFirstMenuState.Data).bannerImg, - bannerTitle = (firstMenuWithBannerState as HomeViewModel.BannerWithFirstMenuState.Data).bannerTitle, - firstMenu = (firstMenuWithBannerState as HomeViewModel.BannerWithFirstMenuState.Data).firstMenu!!, - ) - Button( - isEnabled = true, - btnText = "# 향bti 검사하기", - onClick = { onHbtiClick() }, - buttonModifier = Modifier.background(color = CustomColor.gray4).fillMaxWidth(0.9f) - .height(47.dp), - textColor = Color.White, - textSize = 14, - radious = 8 - ) - } + itemsIndexed( + listOf("TopMenu", "BottomMenu") + ) { idx, item -> + when (idx) { + 0 -> TopMenu(firstMenuWithBannerState, onPerfumeClick, onHbtiClick) + 1 -> BottomMenu(bottomMenuState, onPerfumeClick, onAllPerfumeClick) } + } + } - is HomeViewModel.BannerWithFirstMenuState.Error -> { +} - } +@Composable +fun TopMenu( + firstMenuWithBannerState: HomeViewModel.BannerWithFirstMenuState, onPerfumeClick: (perfumeId: Int) -> Unit, + onHbtiClick: () -> Unit, +) { + when (firstMenuWithBannerState) { + is HomeViewModel.BannerWithFirstMenuState.Loading -> { + AppLoadingScreen() } - when (bottomMenuState) { - is HomeViewModel.BottomMenuState.Loading -> { - AppLoadingScreen() - } - - is HomeViewModel.BottomMenuState.Data -> { - BottomMenuContent( - onPerfumeClick = { onPerfumeClick(it) }, - onAllPerfumeClick = { onAllPerfumeClick(it) }, - (bottomMenuState as HomeViewModel.BottomMenuState.Data).bottomMenu!! + is HomeViewModel.BannerWithFirstMenuState.Data -> { + Column( + modifier = Modifier.fillMaxWidth().padding(horizontal = 17.dp).padding(vertical = 10.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + FirstMenuWithBannerContent( + onHbtiClick = { onHbtiClick() }, + bannerImgUrl = (firstMenuWithBannerState as HomeViewModel.BannerWithFirstMenuState.Data).bannerImg, ) } + FirstMenuView( + (firstMenuWithBannerState as HomeViewModel.BannerWithFirstMenuState.Data).firstMenu!!, + { onPerfumeClick(it) }) + } - is HomeViewModel.BottomMenuState.Error -> { + is HomeViewModel.BannerWithFirstMenuState.Error -> { - } } } } +@Composable +fun BottomMenu( + bottomMenuState: HomeViewModel.BottomMenuState, onPerfumeClick: (perfumeId: Int) -> Unit, + onAllPerfumeClick: (screenId: AllPerfumeScreenId) -> Unit, +) { + when (bottomMenuState) { + is HomeViewModel.BottomMenuState.Loading -> { + AppLoadingScreen() + } + + is HomeViewModel.BottomMenuState.Data -> { + BottomMenuContent( + onPerfumeClick = { onPerfumeClick(it) }, + onAllPerfumeClick = { onAllPerfumeClick(it) }, + (bottomMenuState as HomeViewModel.BottomMenuState.Data).bottomMenu!! + ) + HmoaCompanyMetaData() + } + + is HomeViewModel.BottomMenuState.Error -> { + + } + } +} + +@Composable +private fun HmoaCompanyMetaData() { + Column( + modifier = Modifier.background(color = Color.Black).fillMaxWidth().padding(top = 32.dp, bottom = 36.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + Text( + text = "사업자 번호: 554-20-01858", + textAlign = TextAlign.Start, + fontSize = 12.sp, + fontWeight = FontWeight.Medium, + fontFamily = CustomFont.regular, + color = Color.White, + lineHeight = 16.sp + ) + Text( + text = "향모아 / 대표자 : 박태성", + textAlign = TextAlign.Start, + fontSize = 12.sp, + fontWeight = FontWeight.Medium, + fontFamily = CustomFont.regular, + color = Color.White, + lineHeight = 16.sp + ) + Text( + text = "개인정보보호책임자 : 이종현", + textAlign = TextAlign.Start, + fontSize = 12.sp, + fontWeight = FontWeight.Medium, + fontFamily = pretendard, + color = Color.White, + lineHeight = 16.sp + ) + Text( + text = "통신판매업 : 제 2028-화성동탄-0976호", + textAlign = TextAlign.Start, + fontSize = 12.sp, + fontWeight = FontWeight.Medium, + fontFamily = pretendard, + color = Color.White, + lineHeight = 16.sp + ) + Text( + text = "주소 : 화성시 동탄지성로11, 714-B03호", + textAlign = TextAlign.Start, + fontSize = 12.sp, + fontWeight = FontWeight.Medium, + fontFamily = pretendard, + color = Color.White, + lineHeight = 16.sp + ) + Text( + text = "고객센터 : 070-8080-3309", + textAlign = TextAlign.Start, + fontSize = 12.sp, + fontWeight = FontWeight.Medium, + fontFamily = pretendard, + color = Color.White, + lineHeight = 16.sp + ) + } +} + @Composable private fun FirstMenuWithBannerContent( - onPerfumeClick: (perfumeId: Int) -> Unit, + onHbtiClick: () -> Unit, bannerImgUrl: String?, - bannerTitle: String?, - firstMenu: HomeMenuDefaultResponseDto, ) { Column( - modifier = Modifier.fillMaxWidth(), - horizontalAlignment = Alignment.Start, + modifier = Modifier.fillMaxWidth().background( + color = Color.Black, + shape = RoundedCornerShape( + topStart = 12.dp, + topEnd = 12.dp, + bottomStart = 12.dp, + bottomEnd = 12.dp + ) + ).border( + width = 1.dp, color = Color.Black, shape = RoundedCornerShape( + topStart = 12.dp, + topEnd = 12.dp, + bottomStart = 12.dp, + bottomEnd = 12.dp + ) + ).padding(bottom = 10.dp), + horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { - ImageView( - imageUrl = bannerImgUrl, - width = 2f, - height = 1f, - backgroundColor = Color.White, - ContentScale.FillWidth - ) - Row( - modifier = Modifier - .fillMaxWidth() - .background(CustomColor.gray7) - .padding(vertical = 12.dp) - .padding(horizontal = 16.dp), verticalAlignment = Alignment.CenterVertically + Column( + modifier = Modifier.padding(top = 24.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center ) { Text( - bannerTitle ?: "글씨가 없습니다", + text = "무료 향BTI 검사 후", + textAlign = TextAlign.Start, + fontSize = 20.sp, + fontWeight = FontWeight.Medium, + fontFamily = CustomFont.regular, + color = Color.White + ) + Text( + text = "당신만의 향을 찾아보세요", textAlign = TextAlign.Start, - fontSize = 14.sp, + fontSize = 20.sp, fontWeight = FontWeight.Medium, - fontFamily = CustomFont.regular + fontFamily = CustomFont.regular, + color = Color.White + ) + } + Column( + modifier = Modifier.padding(horizontal = 22.dp).padding(bottom = 10.dp, top = 28.dp).fillMaxWidth(0.8f) + .background(Color.Black) + ) { + ImageView( + imageUrl = bannerImgUrl, + width = 2f, + height = 1f, + backgroundColor = Color.White, + ContentScale.FillWidth ) } - FirstMenuView(firstMenu, { onPerfumeClick(it) }) + Button( + isEnabled = true, + btnText = "# 향bti 검사하기", + onClick = { onHbtiClick() }, + buttonModifier = Modifier.background(color = CustomColor.gray4).fillMaxWidth(0.9f) + .height(47.dp), + textColor = Color.White, + textSize = 14, + radious = 8 + ) } } @@ -339,15 +464,7 @@ fun ImageWithTitleView( private fun HomePreview() { Column(horizontalAlignment = Alignment.CenterHorizontally) { Box(contentAlignment = Alignment.Center, modifier = Modifier.fillMaxWidth()) { - FirstMenuWithBannerContent( - {}, "", "시향지 체험단 모집 ~09.18", HomeMenuDefaultResponseDto( - listOf( - HomeMenuPerfumeResponseDto("딥디크", "", 1, "오 로즈 오 드 뚜왈렛 50ml"), - HomeMenuPerfumeResponseDto("딥디크", "", 1, "오 로즈 오 드 뚜왈렛 50ml"), - HomeMenuPerfumeResponseDto("딥디크", "", 1, "오 로즈 오 드 뚜왈렛 50ml") - ), "겨울 이 향수 어떠세요?" - ) - ) + FirstMenuWithBannerContent({}, "") Button( isEnabled = true, btnText = "향bti 검사하기", @@ -380,4 +497,4 @@ private fun HomePreview() { ) ) ) -} \ No newline at end of file +} diff --git a/feature-home/src/main/java/com/hmoa/feature_home/viewmodel/HomeViewModel.kt b/feature-home/src/main/java/com/hmoa/feature_home/viewmodel/HomeViewModel.kt index f68c93cea..017faac63 100644 --- a/feature-home/src/main/java/com/hmoa/feature_home/viewmodel/HomeViewModel.kt +++ b/feature-home/src/main/java/com/hmoa/feature_home/viewmodel/HomeViewModel.kt @@ -34,16 +34,16 @@ class HomeViewModel @Inject constructor( is Result.Success -> { _firstMenuWithBannerState.update { it } _firstMenuWithBannerState.value = BannerWithFirstMenuState.Data( - bannerImg = it.data.data!!.mainImage, - bannerTitle = it.data.data!!.banner, - firstMenu = it.data.data!!.firstMenu + bannerImg = it.data.data?.mainImage, + bannerTitle = it.data.data?.banner, + firstMenu = it.data.data?.firstMenu ) } - is Result.Error -> {}//TODO() + is Result.Error -> {} is Result.Loading -> { BannerWithFirstMenuState.Loading - }//TODO() + } } } } @@ -90,4 +90,4 @@ class HomeViewModel @Inject constructor( data object Error : BottomMenuState } -} \ No newline at end of file +} diff --git a/feature-magazine/src/main/java/com/hmoa/feature_magazine/Screen/MagazineMain.kt b/feature-magazine/src/main/java/com/hmoa/feature_magazine/Screen/MagazineMain.kt index 2dd497f41..5a2eadc21 100644 --- a/feature-magazine/src/main/java/com/hmoa/feature_magazine/Screen/MagazineMain.kt +++ b/feature-magazine/src/main/java/com/hmoa/feature_magazine/Screen/MagazineMain.kt @@ -493,4 +493,4 @@ private fun ReviewContent( overflow = TextOverflow.Ellipsis ) } -} \ No newline at end of file +} diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/EditProfilePage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/EditProfilePage.kt index a134e0260..5bb63e318 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/EditProfilePage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/EditProfilePage.kt @@ -205,4 +205,4 @@ private fun EditProfileButton( ) } } -} \ No newline at end of file +} diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyBirthPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyBirthPage.kt index cea2cef61..20749c5ec 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyBirthPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyBirthPage.kt @@ -182,4 +182,4 @@ fun BrithTest(){ SelectBirthContent( initBirth = initBirth, saveBirth = { }, navBack = {} ) -} \ No newline at end of file +} diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyCommentPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyCommentPage.kt index 6f54b8947..3a494088e 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyCommentPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyCommentPage.kt @@ -182,4 +182,4 @@ private fun TypeRow( selected = type == MyPageCategory.게시글 ) } -} \ No newline at end of file +} diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyFavoriteCommentPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyFavoriteCommentPage.kt index 92aec4fc3..48a33a3c5 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyFavoriteCommentPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyFavoriteCommentPage.kt @@ -181,4 +181,4 @@ private fun TypeRow( selected = type == MyPageCategory.게시글 ) } -} \ No newline at end of file +} diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyFavoritePrefumePage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyFavoritePrefumePage.kt index 8550c91cc..10920e942 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyFavoritePrefumePage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyFavoritePrefumePage.kt @@ -1,4 +1,4 @@ -package com.hmoa.feature_like.Screen +package com.hmoa.feature_userinfo.screen import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background @@ -249,4 +249,4 @@ private fun LikePerfumeListByGrid( ) } } -} \ No newline at end of file +} diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyGenderPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyGenderPage.kt index 848fba9a7..ceadbe92e 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyGenderPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyGenderPage.kt @@ -116,4 +116,4 @@ private fun SelectGenderContent( onClick = { saveGender(currentGender) } ) } -} \ No newline at end of file +} diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyPage.kt index 09a8552bd..a0955b0d8 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyPage.kt @@ -12,15 +12,7 @@ import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.background import androidx.compose.foundation.clickable -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.size +import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.material.icons.Icons @@ -29,12 +21,7 @@ import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton 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.rememberCoroutineScope -import androidx.compose.runtime.setValue +import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -53,11 +40,7 @@ import com.google.android.gms.oss.licenses.OssLicensesMenuActivity import com.hmoa.core_common.ErrorUiState import com.hmoa.core_common.checkPermission import com.hmoa.core_designsystem.R -import com.hmoa.core_designsystem.component.AppLoadingScreen -import com.hmoa.core_designsystem.component.CircleImageView -import com.hmoa.core_designsystem.component.ErrorUiSetView -import com.hmoa.core_designsystem.component.OnAndOffBtn -import com.hmoa.core_designsystem.component.TopBar +import com.hmoa.core_designsystem.component.* import com.hmoa.core_designsystem.theme.CustomColor import com.hmoa.core_domain.entity.data.ColumnData import com.hmoa.core_domain.entity.navigation.UserInfoRoute diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/RefundPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/RefundPage.kt index 00cb4b22b..c239d999a 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/RefundPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/RefundPage.kt @@ -297,4 +297,4 @@ private fun ReturnOrRefundUITest(){ navBack = {}, navLogin = {} ) -} \ No newline at end of file +} diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/navigation/NavGraph.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/navigation/NavGraph.kt index 48bef1443..26c2bdc4c 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/navigation/NavGraph.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/navigation/NavGraph.kt @@ -9,20 +9,8 @@ import androidx.navigation.navArgument import com.example.userinfo.MyPageRoute import com.hmoa.core_domain.entity.navigation.HbtiRoute import com.hmoa.core_domain.entity.navigation.UserInfoRoute -import com.hmoa.feature_like.Screen.MyFavoritePerfumeRoute import com.hmoa.feature_userinfo.MyFavoriteCommentRoute -import com.hmoa.feature_userinfo.screen.EditProfileRoute -import com.hmoa.feature_userinfo.screen.MyActivityRoute -import com.hmoa.feature_userinfo.screen.MyBirthRoute -import com.hmoa.feature_userinfo.screen.MyCommentRoute -import com.hmoa.feature_userinfo.screen.MyGenderRoute -import com.hmoa.feature_userinfo.screen.MyInfoRoute -import com.hmoa.feature_userinfo.screen.MyPostRoute -import com.hmoa.feature_userinfo.screen.MyReviewRoute -import com.hmoa.feature_userinfo.screen.NoAuthMyPage -import com.hmoa.feature_userinfo.screen.OrderRecordRoute -import com.hmoa.feature_userinfo.screen.RefundRecordRoute -import com.hmoa.feature_userinfo.screen.RefundRoute +import com.hmoa.feature_userinfo.screen.* //graph 이동 fun NavController.navigateToUserInfoGraph() = navigate(UserInfoRoute.UserInfoGraph.name) @@ -62,8 +50,10 @@ fun NavController.navigateToRefund(type: String, orderId: Int) = navigate("${UserInfoRoute.RefundRoute.name}/${type}/${orderId}") //주문 내역 -fun NavController.navigateToOrderRecord(befRoute: UserInfoRoute) = navigate(UserInfoRoute.OrderRecordRoute.name){ - if(befRoute == UserInfoRoute.RefundRoute){ popUpTo(route = "${UserInfoRoute.RefundRoute.name}/{type}/{orderId}"){inclusive = true} } +fun NavController.navigateToOrderRecord(befRoute: UserInfoRoute) = navigate(UserInfoRoute.OrderRecordRoute.name) { + if (befRoute == UserInfoRoute.RefundRoute) { + popUpTo(route = "${UserInfoRoute.RefundRoute.name}/{type}/{orderId}") { inclusive = true } + } } //환불 & 반품 내역 @@ -205,4 +195,4 @@ fun NavGraphBuilder.nestedUserInfoGraph( MyReviewRoute(navReview = navReview, navBack = navBack, navLogin = navLogin) } } -} \ No newline at end of file +} diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyBirthViewModel.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyBirthViewModel.kt index 76f9398f5..cd0187560 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyBirthViewModel.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyBirthViewModel.kt @@ -103,4 +103,4 @@ sealed interface MyBirthUiState { val defaultBirth: Int ) : MyBirthUiState data object Loading : MyBirthUiState -} \ No newline at end of file +} diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyGenderViewModel.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyGenderViewModel.kt index ea629579d..de1b24137 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyGenderViewModel.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyGenderViewModel.kt @@ -2,22 +2,12 @@ package com.hmoa.feature_userinfo.viewModel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.hmoa.core_common.ErrorMessageType -import com.hmoa.core_common.ErrorUiState -import com.hmoa.core_common.Result -import com.hmoa.core_common.asResult -import com.hmoa.core_common.handleErrorType +import com.hmoa.core_common.* import com.hmoa.core_domain.repository.MemberRepository import com.hmoa.core_domain.usecase.GetMyUserInfoUseCase import com.hmoa.core_model.request.SexRequestDto import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.stateIn -import kotlinx.coroutines.flow.update +import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import javax.inject.Inject @@ -47,23 +37,25 @@ class MyGenderViewModel @Inject constructor( started = SharingStarted.WhileSubscribed(5_000), initialValue = ErrorUiState.Loading ) - val uiState: StateFlow = errorUiState.map {errState -> + val uiState: StateFlow = errorUiState.map { errState -> if (errState is ErrorUiState.ErrorData && errState.isValidate()) throw Exception("") val result = getMyUserInfoUseCase() - if (result.errorMessage != null) {throw Exception(result.errorMessage!!.message)} + if (result.errorMessage != null) { + throw Exception(result.errorMessage!!.message) + } result.data }.asResult().map { result -> when (result) { Result.Loading -> MyGenderUiState.Loading is Result.Success -> MyGenderUiState.Success(result.data!!.gender) is Result.Error -> { - if (result.exception.message != ""){ + if (result.exception.message != "") { handleErrorType( error = result.exception, onExpiredTokenError = { expiredTokenErrorState.update { true } }, - onWrongTypeTokenError = { wrongTypeTokenErrorState.update{true}}, - onUnknownError = {unLoginedErrorState.update{true}}, - onGeneralError = {generalErrorState.update{Pair(true, result.exception.message)}} + onWrongTypeTokenError = { wrongTypeTokenErrorState.update { true } }, + onUnknownError = { unLoginedErrorState.update { true } }, + onGeneralError = { generalErrorState.update { Pair(true, result.exception.message) } } ) } MyGenderUiState.Error @@ -74,17 +66,18 @@ class MyGenderViewModel @Inject constructor( started = SharingStarted.WhileSubscribed(3_000), initialValue = MyGenderUiState.Loading ) + //gender 정보 저장 fun saveGender(gender: String, onSuccess: () -> Unit) { val requestDto = SexRequestDto(gender == "남성") viewModelScope.launch { val result = memberRepository.updateSex(requestDto) - if (result.errorMessage != null){ - when(result.errorMessage!!.message){ - ErrorMessageType.UNKNOWN_ERROR.name -> unLoginedErrorState.update{true} - ErrorMessageType.WRONG_TYPE_TOKEN.name -> wrongTypeTokenErrorState.update{true} - ErrorMessageType.EXPIRED_TOKEN.name -> expiredTokenErrorState.update{true} - else -> generalErrorState.update{Pair(true, result.errorMessage!!.message)} + if (result.errorMessage != null) { + when (result.errorMessage!!.message) { + ErrorMessageType.UNKNOWN_ERROR.name -> unLoginedErrorState.update { true } + ErrorMessageType.WRONG_TYPE_TOKEN.name -> wrongTypeTokenErrorState.update { true } + ErrorMessageType.EXPIRED_TOKEN.name -> expiredTokenErrorState.update { true } + else -> generalErrorState.update { Pair(true, result.errorMessage!!.message) } } return@launch } @@ -98,5 +91,6 @@ sealed interface MyGenderUiState { data class Success( val defaultGender: String ) : MyGenderUiState + data object Error : MyGenderUiState -} \ No newline at end of file +} From bb08512bcb0b923559df23fb9fb3002e93890485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 19 Nov 2024 13:12:19 +0900 Subject: [PATCH 25/93] =?UTF-8?q?Feat:=20=ED=96=A5=EB=A3=8C=EC=A3=BC?= =?UTF-8?q?=EB=AC=B8=20=EA=B3=BC=EC=A0=95=20=EC=84=A4=EB=AA=85=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20api=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Hshop/HshopRemoteDataStore.kt | 9 +- .../Hshop/HshopRemoteDataStoreImpl.kt | 53 +++++--- .../component/VerticalStepBar.kt | 15 ++- .../core_domain/repository/HshopRepository.kt | 9 +- .../response/ContentAndTitleResponse.kt | 9 ++ .../response/OrderDescriptionResponseDto.kt | 9 ++ .../hmoa/core_network/service/HshopService.kt | 23 ++-- .../core_repository/HshopRepositoryImpl.kt | 16 ++- feature-hbti/build.gradle.kts | 2 +- .../feature_hbti/navigation/HbtiNavigation.kt | 28 ++-- .../feature_hbti/screen/HbtiProcessScreen.kt | 122 ++++++++++++++---- .../viewmodel/HbtiProcessViewmodel.kt | 104 +++++++++++++++ 12 files changed, 310 insertions(+), 89 deletions(-) create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/ContentAndTitleResponse.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/OrderDescriptionResponseDto.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiProcessViewmodel.kt 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 18fb5cf1c..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,11 +2,7 @@ package com.hmoa.core_datastore.Hshop import ResultResponse import com.hmoa.core_model.request.ProductListRequestDto -import com.hmoa.core_model.response.FinalOrderResponseDto -import com.hmoa.core_model.response.GetMyOrderResponseDto -import com.hmoa.core_model.response.PostNoteOrderResponseDto -import com.hmoa.core_model.response.PostNoteSelectedResponseDto -import com.hmoa.core_model.response.ProductListResponseDto +import com.hmoa.core_model.response.* interface HshopRemoteDataStore { suspend fun getCart(): ResultResponse @@ -16,4 +12,5 @@ interface HshopRemoteDataStore { suspend fun getFinalOrderResult(orderId: Int): ResultResponse suspend fun deleteNoteInOrder(orderId: Int, productId: Int): ResultResponse suspend fun getMyOrders(): ResultResponse> -} \ No newline at end of file + 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 e54901f79..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 @@ -3,29 +3,29 @@ 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.FinalOrderResponseDto -import com.hmoa.core_model.response.GetMyOrderResponseDto -import com.hmoa.core_model.response.PostNoteOrderResponseDto -import com.hmoa.core_model.response.PostNoteSelectedResponseDto -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.decodeFromString import kotlinx.serialization.json.Json import javax.inject.Inject -class HshopRemoteDataStoreImpl @Inject constructor(private val hshopService: HshopService) : HshopRemoteDataStore { +class HshopRemoteDataStoreImpl @Inject constructor( + private val hshopService: HshopService, + private val authenticator: Authenticator +) : HshopRemoteDataStore { override suspend fun getCart(): ResultResponse { val result = ResultResponse() - hshopService.getCart().suspendOnSuccess{ + hshopService.getCart().suspendOnSuccess { result.data = this.data - }.suspendOnError{ + }.suspendOnError { result.errorMessage = Json.decodeFromString(this.message()) } return result } + override suspend fun getNotes(): ResultResponse { var result = ResultResponse() hshopService.getNotes().suspendOnSuccess { @@ -39,9 +39,9 @@ class HshopRemoteDataStoreImpl @Inject constructor(private val hshopService: Hsh override suspend fun postNoteOrder(dto: ProductListRequestDto): ResultResponse { val result = ResultResponse() - hshopService.postNoteOrder(dto).suspendOnSuccess{ + hshopService.postNoteOrder(dto).suspendOnSuccess { result.data = this.data - }.suspendOnError{ + }.suspendOnError { result.errorMessage = Json.decodeFromString(this.message()) } return result @@ -57,11 +57,12 @@ class HshopRemoteDataStoreImpl @Inject constructor(private val hshopService: Hsh } return result } + override suspend fun getFinalOrderResult(orderId: Int): ResultResponse { val result = ResultResponse() - hshopService.getFinalOrderResult(orderId).suspendOnSuccess{ + hshopService.getFinalOrderResult(orderId).suspendOnSuccess { result.data = this.data - }.suspendOnError{ + }.suspendOnError { result.errorMessage = Json.decodeFromString(this.message()) } return result @@ -72,20 +73,36 @@ class HshopRemoteDataStoreImpl @Inject constructor(private val hshopService: Hsh productId: Int ): ResultResponse { val result = ResultResponse() - hshopService.deleteNoteInOrder(orderId, productId).suspendOnSuccess{ + hshopService.deleteNoteInOrder(orderId, productId).suspendOnSuccess { result.data = this.data - }.suspendOnError{ + }.suspendOnError { result.errorMessage = Json.decodeFromString(this.message()) } return result } + override suspend fun getMyOrders(): ResultResponse> { val result = ResultResponse>() - hshopService.getMyOrders().suspendOnError{ + hshopService.getMyOrders().suspendOnError { result.errorMessage = Json.decodeFromString(this.message()) - }.suspendOnSuccess{ + }.suspendOnSuccess { result.data = this.data } return result } -} \ No newline at end of file + + 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.getOrderDescriptions().suspendOnSuccess { result.data = this.data } + }) + } + return result + } +} 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-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 d0d22f7f8..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,11 +2,7 @@ package com.hmoa.core_domain.repository import ResultResponse import com.hmoa.core_model.request.ProductListRequestDto -import com.hmoa.core_model.response.FinalOrderResponseDto -import com.hmoa.core_model.response.GetMyOrderResponseDto -import com.hmoa.core_model.response.PostNoteOrderResponseDto -import com.hmoa.core_model.response.PostNoteSelectedResponseDto -import com.hmoa.core_model.response.ProductListResponseDto +import com.hmoa.core_model.response.* interface HshopRepository { suspend fun getCart(): ResultResponse @@ -16,4 +12,5 @@ interface HshopRepository { suspend fun getFinalOrderResult(orderId: Int): ResultResponse suspend fun deleteNoteInOrder(orderId: Int, productId: Int): ResultResponse suspend fun getMyOrders(): ResultResponse> -} \ No newline at end of file + suspend fun getOrderDescriptions(): ResultResponse +} diff --git a/core-model/src/main/java/com/hmoa/core_model/response/ContentAndTitleResponse.kt b/core-model/src/main/java/com/hmoa/core_model/response/ContentAndTitleResponse.kt new file mode 100644 index 000000000..fa6d908b2 --- /dev/null +++ b/core-model/src/main/java/com/hmoa/core_model/response/ContentAndTitleResponse.kt @@ -0,0 +1,9 @@ +package com.hmoa.core_model.response + +import kotlinx.serialization.Serializable + +@Serializable +data class ContentAndTitle( + val content: String, + val title: String +) diff --git a/core-model/src/main/java/com/hmoa/core_model/response/OrderDescriptionResponseDto.kt b/core-model/src/main/java/com/hmoa/core_model/response/OrderDescriptionResponseDto.kt new file mode 100644 index 000000000..bd7b32da8 --- /dev/null +++ b/core-model/src/main/java/com/hmoa/core_model/response/OrderDescriptionResponseDto.kt @@ -0,0 +1,9 @@ +package com.hmoa.core_model.response + +import kotlinx.serialization.Serializable + +@Serializable +data class OrderDescriptionResponseDto( + val orderDescriptionImgUrl: String, + val orderDescriptions: List +) diff --git a/core-network/src/main/java/com/hmoa/core_network/service/HshopService.kt b/core-network/src/main/java/com/hmoa/core_network/service/HshopService.kt index 0a72d6d97..fc1b3db84 100644 --- a/core-network/src/main/java/com/hmoa/core_network/service/HshopService.kt +++ b/core-network/src/main/java/com/hmoa/core_network/service/HshopService.kt @@ -1,36 +1,37 @@ package com.hmoa.core_network.service import com.hmoa.core_model.request.ProductListRequestDto -import com.hmoa.core_model.response.FinalOrderResponseDto -import com.hmoa.core_model.response.GetMyOrderResponseDto -import com.hmoa.core_model.response.PostNoteOrderResponseDto -import com.hmoa.core_model.response.PostNoteSelectedResponseDto -import com.hmoa.core_model.response.ProductListResponseDto +import com.hmoa.core_model.response.* import com.skydoves.sandwich.ApiResponse -import retrofit2.http.Body -import retrofit2.http.DELETE -import retrofit2.http.GET -import retrofit2.http.POST -import retrofit2.http.Path +import retrofit2.http.* interface HshopService { @GET("/shop/cart") suspend fun getCart(): ApiResponse + @GET("/shop/note") suspend fun getNotes(): ApiResponse + @POST("/shop/note/order") suspend fun postNoteOrder(@Body dto: ProductListRequestDto): ApiResponse + @POST("/shop/note/select") suspend fun postNotesSelected(@Body dto: ProductListRequestDto): ApiResponse + @GET("/shop/note/order/{orderId}") suspend fun getFinalOrderResult( @Path("orderId") orderId: Int ): ApiResponse + @DELETE("/shop/note/order/{orderId}/product/{productId}") suspend fun deleteNoteInOrder( @Path("orderId") orderId: Int, @Path("productId") productId: Int ): ApiResponse + @GET("/shop/order/me") suspend fun getMyOrders(): ApiResponse> -} \ No newline at end of file + + @GET("/shop/order/description") + suspend fun getOrderDescriptions(): ApiResponse +} diff --git a/core-repository/src/main/java/com/hmoa/core_repository/HshopRepositoryImpl.kt b/core-repository/src/main/java/com/hmoa/core_repository/HshopRepositoryImpl.kt index c97c8e53f..c5a407d8a 100644 --- a/core-repository/src/main/java/com/hmoa/core_repository/HshopRepositoryImpl.kt +++ b/core-repository/src/main/java/com/hmoa/core_repository/HshopRepositoryImpl.kt @@ -4,11 +4,7 @@ import ResultResponse import com.hmoa.core_datastore.Hshop.HshopRemoteDataStore import com.hmoa.core_domain.repository.HshopRepository import com.hmoa.core_model.request.ProductListRequestDto -import com.hmoa.core_model.response.FinalOrderResponseDto -import com.hmoa.core_model.response.GetMyOrderResponseDto -import com.hmoa.core_model.response.PostNoteOrderResponseDto -import com.hmoa.core_model.response.PostNoteSelectedResponseDto -import com.hmoa.core_model.response.ProductListResponseDto +import com.hmoa.core_model.response.* import javax.inject.Inject class HshopRepositoryImpl @Inject constructor(private val hshopRemoteDataStore: HshopRemoteDataStore) : @@ -16,6 +12,7 @@ class HshopRepositoryImpl @Inject constructor(private val hshopRemoteDataStore: override suspend fun getCart(): ResultResponse { return hshopRemoteDataStore.getCart() } + override suspend fun getNotesProduct(): ResultResponse { return hshopRemoteDataStore.getNotes() } @@ -23,9 +20,11 @@ class HshopRepositoryImpl @Inject constructor(private val hshopRemoteDataStore: override suspend fun postNoteOrder(dto: ProductListRequestDto): ResultResponse { return hshopRemoteDataStore.postNoteOrder(dto) } + override suspend fun postNotesSelected(dto: ProductListRequestDto): ResultResponse { return hshopRemoteDataStore.postNotesSelected(dto) } + override suspend fun getFinalOrderResult(orderId: Int): ResultResponse { return hshopRemoteDataStore.getFinalOrderResult(orderId) } @@ -36,7 +35,12 @@ class HshopRepositoryImpl @Inject constructor(private val hshopRemoteDataStore: ): ResultResponse { return hshopRemoteDataStore.deleteNoteInOrder(orderId, productId) } + override suspend fun getMyOrders(): ResultResponse> { return hshopRemoteDataStore.getMyOrders() } -} \ No newline at end of file + + override suspend fun getOrderDescriptions(): ResultResponse { + return hshopRemoteDataStore.getOrderDescriptions() + } +} diff --git a/feature-hbti/build.gradle.kts b/feature-hbti/build.gradle.kts index c8697ed63..331c6caca 100644 --- a/feature-hbti/build.gradle.kts +++ b/feature-hbti/build.gradle.kts @@ -117,4 +117,4 @@ dependencies { androidTestImplementation("com.google.dagger:hilt-android-testing:$hilt_version") // ...with Kotlin. kaptAndroidTest("com.google.dagger:hilt-android-compiler:$hilt_version") -} \ No newline at end of file +} diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/navigation/HbtiNavigation.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/navigation/HbtiNavigation.kt index e8e0b3807..42fb13ae1 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/navigation/HbtiNavigation.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/navigation/HbtiNavigation.kt @@ -10,13 +10,13 @@ import com.hmoa.core_domain.entity.navigation.HbtiRoute import com.hmoa.core_domain.entity.navigation.HomeRoute import com.hmoa.core_model.data.NoteProductIds import com.hmoa.feature_hbti.screen.* -import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json fun NavController.navigateToHbti() = navigate("${HbtiRoute.Hbti}") { - popUpTo(HomeRoute.Home.name){inclusive = false} + popUpTo(HomeRoute.Home.name) { inclusive = false } launchSingleTop = true } + fun NavController.navigateToHbtiSurvey() = navigate("${HbtiRoute.HbtiSurvey}") { launchSingleTop = true } fun NavController.navigateToHbtiSurveyResult() = navigate("${HbtiRoute.HbtiSurveyResult}") { launchSingleTop = true } @@ -129,9 +129,10 @@ fun NavGraphBuilder.hbtiSurveyResultScreen( } } -fun NavGraphBuilder.hbtiProcessScreen(onBackClick: () -> Unit, onNextClick: () -> Unit) { +fun NavGraphBuilder.hbtiProcessScreen(navLogin: () -> Unit, onBackClick: () -> Unit, onNextClick: () -> Unit) { composable(route = "${HbtiRoute.HbtiProcess}") { HbtiProcessRoute( + navLogin = navLogin, onBackClick = { onBackClick() }, onNextClick = { onNextClick() }) } @@ -196,6 +197,7 @@ fun NavGraphBuilder.perfumeRecommendationResultRoute( ) } } + fun NavGraphBuilder.order( navBack: () -> Unit, navAddAddress: (String, String) -> Unit, @@ -237,8 +239,8 @@ fun NavGraphBuilder.addAddress( } } -fun NavGraphBuilder.orderResult(navHbti: () -> Unit){ - composable(route = HbtiRoute.OrderResultRoute.name){ +fun NavGraphBuilder.orderResult(navHbti: () -> Unit) { + composable(route = HbtiRoute.OrderResultRoute.name) { OrderResultRoute(navHbti = navHbti) } } @@ -246,13 +248,13 @@ fun NavGraphBuilder.orderResult(navHbti: () -> Unit){ fun NavGraphBuilder.writeReview( navBack: () -> Unit, navReview: (befRoute: HbtiRoute) -> Unit -){ +) { composable( route = "${HbtiRoute.WriteReviewRoute.name}/{orderId}", arguments = listOf( - navArgument("orderId"){type = NavType.IntType} + navArgument("orderId") { type = NavType.IntType } ) - ){ + ) { val orderId = it.arguments?.getInt("orderId") WriteReviewRoute( orderId = orderId, @@ -267,10 +269,10 @@ fun NavGraphBuilder.review( navEditReview: (Int) -> Unit, navLogin: () -> Unit, navWriteReview: (reviewId: Int) -> Unit -){ +) { composable( route = "${HbtiRoute.ReviewRoute.name}" - ){ + ) { ReviewRoute( navBack = navBack, navEditReview = navEditReview, @@ -280,11 +282,11 @@ fun NavGraphBuilder.review( } } -fun NavGraphBuilder.editReview(navReview: (befRoute: HbtiRoute) -> Unit, navLogin: () -> Unit){ +fun NavGraphBuilder.editReview(navReview: (befRoute: HbtiRoute) -> Unit, navLogin: () -> Unit) { composable( route = "${HbtiRoute.EditReviewRoute.name}/{reviewId}", - arguments = listOf(navArgument("reviewId"){type = NavType.IntType}) - ){ + arguments = listOf(navArgument("reviewId") { type = NavType.IntType }) + ) { val reviewId = it.arguments?.getInt("reviewId") EditReviewRoute( reviewId = reviewId, diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiProcessScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiProcessScreen.kt index 2779fe83f..b12a6be5f 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiProcessScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiProcessScreen.kt @@ -1,49 +1,125 @@ package com.hmoa.feature_hbti.screen +import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.hmoa.core_designsystem.R -import com.hmoa.core_designsystem.component.Button -import com.hmoa.core_designsystem.component.TopBar -import com.hmoa.core_designsystem.component.VerticalStepBar +import com.hmoa.core_designsystem.component.* +import com.hmoa.feature_hbti.viewmodel.HbtiProcessUiState +import com.hmoa.feature_hbti.viewmodel.HbtiProcessViewmodel @Composable -fun HbtiProcessRoute(onBackClick: () -> Unit, onNextClick: () -> Unit) { +fun HbtiProcessRoute(navLogin: () -> Unit, onBackClick: () -> Unit, onNextClick: () -> Unit) { HbtiProcessScreen( + navLogin = navLogin, onBackClick = { onBackClick() }, onNextClick = { onNextClick() }) } @Composable -private fun HbtiProcessScreen(onBackClick: () -> Unit, onNextClick: () -> Unit) { - Column( - modifier = Modifier.fillMaxSize().background(color = Color.White).padding(bottom = 40.dp), - verticalArrangement = Arrangement.SpaceBetween - ) { - Column { - TopBar( - title = "향BTI", - titleColor = Color.Black, - navIcon = painterResource(R.drawable.ic_back), - onNavClick = { onBackClick() } +private fun HbtiProcessScreen( + navLogin: () -> Unit, + onBackClick: () -> Unit, + onNextClick: () -> Unit, + viewModel: HbtiProcessViewmodel = hiltViewModel() +) { + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + val errorState by viewModel.errorUiState.collectAsStateWithLifecycle() + + ErrorUiSetView( + onLoginClick = navLogin, + errorUiState = errorState, + onCloseClick = onBackClick + ) + + when (uiState) { + HbtiProcessUiState.Error -> {} + HbtiProcessUiState.Loading -> { + AppLoadingScreen() + } + + is HbtiProcessUiState.Success -> { + HbtiProcessContent( + onBackClick, + onNextClick, + (uiState as HbtiProcessUiState.Success).titles, + (uiState as HbtiProcessUiState.Success).contents, + (uiState as HbtiProcessUiState.Success).descriptionUrl ) - Column(modifier = Modifier.padding(top = 22.dp).padding(horizontal = 16.dp)) { - VerticalStepBar( - arrayOf("향료 선택", "배송", "향수 추천"), - arrayOf("향BTI 검사 이후 추천하는 향료, 원하는 향료 선택(가격대 상이)", "결제 후 1~2일 내 배송 완료", "시향 후 가장 좋았던 향료 선택, 향수 추천 받기") + } + } + +} + +@OptIn(ExperimentalFoundationApi::class) +@Composable +private fun HbtiProcessContent( + onBackClick: () -> Unit, + onNextClick: () -> Unit, + titles: List, + contents: List, + imgUrl: String, +) { + Box( + modifier = Modifier.fillMaxSize() + .background(color = Color.White).padding(bottom = 40.dp), + ) { + LazyColumn { + stickyHeader { + TopBar( + color = Color.White, + title = "향BTI", + titleColor = Color.Black, + navIcon = painterResource(R.drawable.ic_back), + onNavClick = { onBackClick() } ) } + itemsIndexed(listOf("OrderSteps", "ImgUrl")) { idx, item -> + when (idx) { + 0 -> { + Column(modifier = Modifier.padding(top = 22.dp).padding(horizontal = 16.dp)) { + VerticalStepBar( + titles = titles, + contents = contents + ) + } + } + + 1 -> { + Column(modifier = Modifier.padding(top = 17.dp).padding(horizontal = 22.dp)) { + ImageView( + imageUrl = imgUrl, + backgroundColor = Color.White, + contentScale = ContentScale.Inside, + width = 1f, + height = 1f + ) + } + } + } + } } - Column(modifier = Modifier.padding(horizontal = 16.dp)) { + Column( + modifier = Modifier.padding(horizontal = 16.dp).fillMaxWidth() + .background(color = Color.White) + .align(Alignment.BottomCenter) + ) { Button( isEnabled = true, - btnText = "다음", + btnText = "추천받은 향료를 시향해보세요", onClick = { onNextClick() }, buttonModifier = Modifier.fillMaxWidth(1f).height(52.dp).background(color = Color.Black), textSize = 18, @@ -57,5 +133,5 @@ private fun HbtiProcessScreen(onBackClick: () -> Unit, onNextClick: () -> Unit) @Preview @Composable private fun HbtiProcessScreenPreview() { - HbtiProcessScreen(onBackClick = {}, onNextClick = {}) -} \ No newline at end of file + HbtiProcessScreen(navLogin = {}, onBackClick = {}, onNextClick = {}) +} diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiProcessViewmodel.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiProcessViewmodel.kt new file mode 100644 index 000000000..cb39c21c8 --- /dev/null +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiProcessViewmodel.kt @@ -0,0 +1,104 @@ +package com.hmoa.feature_hbti.viewmodel + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.hmoa.core_common.* +import com.hmoa.core_domain.repository.HshopRepository +import com.hmoa.core_model.response.OrderDescriptionResponseDto +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.* +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class HbtiProcessViewmodel @Inject constructor(private val hbtiRepository: HshopRepository) : ViewModel() { + private var _titlesState = MutableStateFlow>(emptyList()) + private var _contentsState = MutableStateFlow>(emptyList()) + private var _imgUrlState = MutableStateFlow("") + private var expiredTokenErrorState = MutableStateFlow(false) + private var wrongTypeTokenErrorState = MutableStateFlow(false) + private var unLoginedErrorState = MutableStateFlow(false) + private var generalErrorState = MutableStateFlow>(Pair(false, null)) + val errorUiState: StateFlow = combine( + expiredTokenErrorState, + wrongTypeTokenErrorState, + unLoginedErrorState, + generalErrorState + ) { expiredTokenError, wrongTypeTokenError, unknownError, generalError -> + ErrorUiState.ErrorData( + expiredTokenError = expiredTokenError, + wrongTypeTokenError = wrongTypeTokenError, + unknownError = unknownError, + generalError = generalError + ) + }.stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5_000), + initialValue = ErrorUiState.Loading + ) + val uiState: StateFlow = + combine(_titlesState, _contentsState, _imgUrlState) { titles, contents, imgUrl -> + HbtiProcessUiState.Success( + titles = titles, + contents = contents, + descriptionUrl = imgUrl + ) + }.stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5_000), + initialValue = HbtiProcessUiState.Loading + ) + + init { + getOrderProcessDescription() + } + + fun getOrderProcessDescription() { + viewModelScope.launch { + flow { + val response = hbtiRepository.getOrderDescriptions() + response.emitOrThrow { emit(it) } + }.asResult().collectLatest { result -> + when (result) { + is Result.Success -> { + updateTitlesAndContents(result.data.data) + _imgUrlState.update { result.data.data?.orderDescriptionImgUrl ?: "" } + } + + is Result.Error -> { + handleErrorType( + error = result.exception, + onExpiredTokenError = { expiredTokenErrorState.update { true } }, + onUnknownError = { unLoginedErrorState.update { true } }, + onWrongTypeTokenError = { wrongTypeTokenErrorState.update { true } }, + onGeneralError = { generalErrorState.update { Pair(true, result.exception.message) } } + ) + } + + Result.Loading -> {} + } + } + } + } + + fun updateTitlesAndContents(result: OrderDescriptionResponseDto?) { + val titles = mutableListOf() + val contents = mutableListOf() + result?.orderDescriptions?.map { + titles.add(it.title) + contents.add(it.content) + } + _titlesState.update { titles } + _contentsState.update { contents } + } +} + +sealed interface HbtiProcessUiState { + data object Error : HbtiProcessUiState + data object Loading : HbtiProcessUiState + data class Success( + val titles: List, + val contents: List, + val descriptionUrl: String, + ) : HbtiProcessUiState +} From 2b4ffc0ad4cecd6ff7fd02a7e3e684178cfa8d86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 19 Nov 2024 14:01:40 +0900 Subject: [PATCH 26/93] =?UTF-8?q?Feat:=20=ED=96=A5=EB=A3=8C=EC=A3=BC?= =?UTF-8?q?=EB=AC=B8=20=EA=B3=BC=EC=A0=95=20=EC=84=A4=EB=AA=85=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EB=84=A4=EB=B9=84=EA=B2=8C=EC=9D=B4=EC=85=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/hmoa/app/navigation/NavHost.kt | 82 ++----------------- 1 file changed, 7 insertions(+), 75 deletions(-) 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 fef5d6235..8c5150beb 100644 --- a/app/src/main/java/com/hmoa/app/navigation/NavHost.kt +++ b/app/src/main/java/com/hmoa/app/navigation/NavHost.kt @@ -3,61 +3,14 @@ package com.hmoa.app.navigation import androidx.compose.runtime.Composable import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost -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_authentication.navigation.* 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.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_community.Navigation.* import com.hmoa.feature_fcm.alarmRoute -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_hbti.navigation.* +import com.hmoa.feature_home.navigation.* import com.hmoa.feature_hpedia.Navigation.navigateToHPedia import com.hmoa.feature_hpedia.Navigation.navigateToHPediaDescRoute import com.hmoa.feature_hpedia.Navigation.navigateToHPediaSearchRoute @@ -65,30 +18,8 @@ import com.hmoa.feature_hpedia.Navigation.nestedHPediaGraph 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.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 +import com.hmoa.feature_perfume.navigation.* +import com.hmoa.feature_userinfo.navigation.* @Composable fun SetUpNavGraph( @@ -262,6 +193,7 @@ fun SetUpNavGraph( onBackClick = navController::navigateToBack, ) hbtiProcessScreen( + navLogin = navController::navigateToLogin, onBackClick = navController::navigateToBack, onNextClick = navController::navigateToNotePick ) From 02db089fc033fee061f4a89ae5e22a35e92a462b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 19 Nov 2024 16:46:08 +0900 Subject: [PATCH 27/93] =?UTF-8?q?Feat:=20=EA=B0=80=EA=B2=A9=EB=8C=80=20?= =?UTF-8?q?=ED=96=A5=EC=88=98=EC=B6=94=EC=B2=9C=20=EA=B2=B0=EA=B3=BC=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PerfumeRecommendationResultScreen.kt | 83 +++++++++++++------ .../PerfumeRecommendationResultViewModel.kt | 25 ++++-- 2 files changed, 79 insertions(+), 29 deletions(-) diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/PerfumeRecommendationResultScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/PerfumeRecommendationResultScreen.kt index f7eb32702..711737145 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/PerfumeRecommendationResultScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/PerfumeRecommendationResultScreen.kt @@ -1,6 +1,7 @@ package com.hmoa.feature_hbti.screen import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* @@ -9,6 +10,7 @@ import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource @@ -19,8 +21,10 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.hmoa.core_designsystem.R import com.hmoa.core_designsystem.component.* import com.hmoa.core_designsystem.theme.CustomColor +import com.hmoa.core_designsystem.theme.CustomFont import com.hmoa.core_model.response.PerfumeRecommendResponseDto import com.hmoa.feature_hbti.viewmodel.PerfumeRecommendationResultViewModel import com.hmoa.feature_hbti.viewmodel.PerfumeResultUiState @@ -30,7 +34,7 @@ fun PerfumeRecommendationResultRoute( navBack: () -> Unit, navPerfume: (Int) -> Unit, navHome: () -> Unit, - navLogin:()->Unit, + navLogin: () -> Unit, viewModel: PerfumeRecommendationResultViewModel = hiltViewModel() ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() @@ -44,6 +48,7 @@ fun PerfumeRecommendationResultRoute( perfumes = (uiState as PerfumeResultUiState.Success).perfumes ?: emptyList(), isPriceSortedSelected = (uiState as PerfumeResultUiState.Success).isPriceSortedSelected, isNoteSortedSelected = (uiState as PerfumeResultUiState.Success).isNoteSortedSelected, + isEmptyPriceContentNeedState = (uiState as PerfumeResultUiState.Success).isEmptyPriceContentNeedState, navBack = navBack, navPerfume = navPerfume, onClickButton = navHome, @@ -64,10 +69,11 @@ fun PerfumeRecommendationResultRoute( } @Composable -private fun PerfumeCommentResultContent( +fun PerfumeCommentResultContent( perfumes: List, isPriceSortedSelected: Boolean, isNoteSortedSelected: Boolean, + isEmptyPriceContentNeedState: Boolean, onClickButton: () -> Unit, onClickPriceSorted: () -> Unit, onClickNoteSorted: () -> Unit, @@ -116,10 +122,10 @@ private fun PerfumeCommentResultContent( modifier = Modifier.clickable { onClickNoteSorted() }.padding(start = 7.dp) ) } - /** 임시 더미 데이터 */ PerfumeResult( perfumes = perfumes, - navPerfume = navPerfume + navPerfume = navPerfume, + isEmptyPriceContentNeedState = isEmptyPriceContentNeedState ) Spacer(Modifier.height(30.dp)) } @@ -139,10 +145,34 @@ private fun PerfumeCommentResultContent( } } +@Composable +fun EmptyPricePerfumeRecommendationScreen() { + Column(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 = "설정하신 가격대 내에\n해당하는 향수가 없습니다.", + fontSize = 20.sp, + fontFamily = CustomFont.bold, + ) + Spacer(Modifier.height(17.dp)) + Text( + text = "가격대를 재설정 해주세요.", + fontSize = 16.sp, + fontFamily = CustomFont.regular, + ) + } +} + @OptIn(ExperimentalFoundationApi::class) @Composable private fun PerfumeResult( perfumes: List, + isEmptyPriceContentNeedState: Boolean, navPerfume: (Int) -> Unit, ) { val pagerState = rememberPagerState(pageCount = { perfumes.size }) @@ -151,24 +181,28 @@ private fun PerfumeResult( horizontalAlignment = androidx.compose.ui.Alignment.CenterHorizontally ) { Spacer(Modifier.height(20.dp)) - HorizontalPager( - modifier = Modifier - .padding(horizontal = 25.dp).fillMaxWidth(), - state = pagerState, - contentPadding = PaddingValues(end = 80.dp) - ) { page -> - val perfume = perfumes[page] - Column(modifier = Modifier.padding(end = 15.dp)) { - LikeRowItem( - brand = perfume.brandname ?: "", - itemPicture = perfume.perfumeImageUrl ?: "", - price = perfume.price.toString(), - itemNameKo = perfume.perfumeName ?: "", - itemNameEng = perfume.perfumeEnglishName ?: "", - onClickClose = { /** 아무 이벤트도 실행하지 않음 */ }, - navPerfume = { navPerfume(perfume.perfumeId ?: 0) }, - isCloseButtonExist = false - ) + if (isEmptyPriceContentNeedState) { + EmptyPricePerfumeRecommendationScreen() + } else { + HorizontalPager( + modifier = Modifier + .padding(horizontal = 25.dp).fillMaxWidth(), + state = pagerState, + contentPadding = PaddingValues(end = 80.dp) + ) { page -> + val perfume = perfumes[page] + Column(modifier = Modifier.padding(end = 15.dp)) { + LikeRowItem( + brand = perfume.brandname ?: "", + itemPicture = perfume.perfumeImageUrl ?: "", + price = perfume.price.toString(), + itemNameKo = perfume.perfumeName ?: "", + itemNameEng = perfume.perfumeEnglishName ?: "", + onClickClose = { /** 아무 이벤트도 실행하지 않음 */ }, + navPerfume = { navPerfume(perfume.perfumeId ?: 0) }, + isCloseButtonExist = false + ) + } } } } @@ -195,6 +229,7 @@ fun PerfumeRecommendationsResultPreview() { navPerfume = {}, onClickButton = {}, onClickPriceSorted = {}, - onClickNoteSorted = {} + onClickNoteSorted = {}, + isEmptyPriceContentNeedState = false ) -} \ No newline at end of file +} diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/PerfumeRecommendationResultViewModel.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/PerfumeRecommendationResultViewModel.kt index 6718226e4..b4fed3368 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/PerfumeRecommendationResultViewModel.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/PerfumeRecommendationResultViewModel.kt @@ -14,8 +14,11 @@ class PerfumeRecommendationResultViewModel @Inject constructor( private val surveyRepository: SurveyRepository, ) : ViewModel() { private var _perfumesState = MutableStateFlow>(listOf()) + val perfumesState: StateFlow> = _perfumesState private var _isPriceSortedSelectedState = MutableStateFlow(true) private var _isNoteSortedSelectedState = MutableStateFlow(false) + private var _isEmptyPriceContentNeedState = MutableStateFlow(true) + val isEmptyPriceContentNeedState: StateFlow = _isEmptyPriceContentNeedState private var expiredTokenErrorState = MutableStateFlow(false) private var wrongTypeTokenErrorState = MutableStateFlow(false) private var unLoginedErrorState = MutableStateFlow(false) @@ -42,10 +45,11 @@ class PerfumeRecommendationResultViewModel @Inject constructor( combine( _perfumesState, _isPriceSortedSelectedState, - _isNoteSortedSelectedState - ) { perfumes, isPriceSortedSelected, isNoteSortedSelected -> + _isNoteSortedSelectedState, + _isEmptyPriceContentNeedState + ) { perfumes, isPriceSortedSelected, isNoteSortedSelected, isEmptyPriceContentNeedState -> PerfumeResultUiState.Success( - perfumes, isPriceSortedSelected, isNoteSortedSelected + perfumes, isPriceSortedSelected, isNoteSortedSelected, isEmptyPriceContentNeedState ) }.stateIn( scope = viewModelScope, @@ -60,6 +64,7 @@ class PerfumeRecommendationResultViewModel @Inject constructor( fun insertPriceSortedPerfumes() { _isPriceSortedSelectedState.update { true } _isNoteSortedSelectedState.update { false } + validatePricePerfumeRecommendation(surveyRepository.getPriceSortedPerfumeRecommendsResult().data?.recommendPerfumes) _perfumesState.update { surveyRepository.getPriceSortedPerfumeRecommendsResult().data?.recommendPerfumes ?: listOf() } @@ -68,10 +73,19 @@ class PerfumeRecommendationResultViewModel @Inject constructor( fun insertNoteSortedPerfumes() { _isPriceSortedSelectedState.update { false } _isNoteSortedSelectedState.update { true } + _isEmptyPriceContentNeedState.update { false } _perfumesState.update { surveyRepository.getNoteSortedPerfumeRecommendsResult().data?.recommendPerfumes ?: listOf() } } + + fun validatePricePerfumeRecommendation(recommendation: List?) { + if (recommendation.isNullOrEmpty()) { + _isEmptyPriceContentNeedState.update { true } + } else { + _isEmptyPriceContentNeedState.update { false } + } + } } sealed interface PerfumeResultUiState { @@ -79,8 +93,9 @@ sealed interface PerfumeResultUiState { data class Success( val perfumes: List?, val isPriceSortedSelected: Boolean, - val isNoteSortedSelected: Boolean + val isNoteSortedSelected: Boolean, + val isEmptyPriceContentNeedState: Boolean ) : PerfumeResultUiState data object Error : PerfumeResultUiState -} \ No newline at end of file +} From 284607a9157ad6160220c6caf4f490994c292822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 19 Nov 2024 16:46:41 +0900 Subject: [PATCH 28/93] =?UTF-8?q?Test:=20=ED=96=A5=EC=88=98=20=EC=B6=94?= =?UTF-8?q?=EC=B2=9C=EA=B2=B0=EA=B3=BC=20=ED=99=94=EB=A9=B4=20UI/=EB=8B=A8?= =?UTF-8?q?=EC=9C=84=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PerfumeRecommendationResultScreenTest.kt | 30 ++++++++ ...erfumeRecommendationResultViewmodelTest.kt | 74 +++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/PerfumeRecommendationResultScreenTest.kt create mode 100644 feature-hbti/src/test/java/com/hmoa/feature_hbti/PerfumeRecommendationResultViewmodelTest.kt diff --git a/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/PerfumeRecommendationResultScreenTest.kt b/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/PerfumeRecommendationResultScreenTest.kt new file mode 100644 index 000000000..6d9cfac89 --- /dev/null +++ b/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/PerfumeRecommendationResultScreenTest.kt @@ -0,0 +1,30 @@ +package com.hmoa.feature_hbti + +import androidx.compose.ui.test.junit4.createComposeRule +import com.hmoa.feature_hbti.screen.PerfumeCommentResultContent +import org.junit.Rule +import org.junit.Test + +class PerfumeRecommendationResultScreenTest { + @get:Rule(order = 0) + val composeTestRule = createComposeRule() + + @Test + fun test_EmptyPriceRecommendation_ShowsEmptyResultInfoScreen() { + composeTestRule.setContent { + PerfumeCommentResultContent( + perfumes = emptyList(), + isPriceSortedSelected = true, + isNoteSortedSelected = false, + isEmptyPriceContentNeedState = true, + onClickButton = {}, + onClickPriceSorted = {}, + onClickNoteSorted = {}, + navBack = {}, + navPerfume = {} + ) + } + Thread.sleep(4000) + } + +} diff --git a/feature-hbti/src/test/java/com/hmoa/feature_hbti/PerfumeRecommendationResultViewmodelTest.kt b/feature-hbti/src/test/java/com/hmoa/feature_hbti/PerfumeRecommendationResultViewmodelTest.kt new file mode 100644 index 000000000..864f32326 --- /dev/null +++ b/feature-hbti/src/test/java/com/hmoa/feature_hbti/PerfumeRecommendationResultViewmodelTest.kt @@ -0,0 +1,74 @@ +package com.hmoa.feature_hbti + +import ResultResponse +import com.hmoa.core_domain.repository.SurveyRepository +import com.hmoa.core_model.response.PerfumeRecommendResponseDto +import com.hmoa.core_model.response.PerfumeRecommendsResponseDto +import com.hmoa.feature_hbti.viewmodel.PerfumeRecommendationResultViewModel +import junit.framework.TestCase +import kotlinx.coroutines.runBlocking +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.mockito.Mockito +import org.mockito.Mockito.mock + +class PerfumeRecommendationResultViewmodelTest : TestCase() { + @get:Rule(order = 0) + val coroutineRule = TestCoroutineRule() + + private val surveyRepository = mock(SurveyRepository::class.java) + lateinit var viewmodel: PerfumeRecommendationResultViewModel + lateinit var notePerfumeRecommendationResult: List + lateinit var pricePerfumeRecommendationResult: List + + @Before + override fun setUp() { + super.setUp() + notePerfumeRecommendationResult = listOf( + PerfumeRecommendResponseDto( + brandname = "샤넬", + perfumeId = 0, + perfumeName = "넘버.1", + perfumeEnglishName = "No.1", + perfumeImageUrl = "", + price = 100000 + ) + ) + pricePerfumeRecommendationResult = listOf() + runBlocking { + Mockito.`when`(surveyRepository.getNoteSortedPerfumeRecommendsResult()) + .thenReturn(ResultResponse(PerfumeRecommendsResponseDto(recommendPerfumes = notePerfumeRecommendationResult))) + Mockito.`when`(surveyRepository.getPriceSortedPerfumeRecommendsResult()) + .thenReturn(ResultResponse(PerfumeRecommendsResponseDto(recommendPerfumes = pricePerfumeRecommendationResult))) + viewmodel = PerfumeRecommendationResultViewModel(surveyRepository) + } + } + + @Test + fun `test_getPriceRecommendationPerfume_EmptyPerfumes`() { + viewmodel.insertPriceSortedPerfumes() + assertEquals(viewmodel.perfumesState.value, emptyList()) + } + + @Test + fun `test_insertNoteAfterInsertPrice_reflectsInNotePerfumes`() { + viewmodel.insertPriceSortedPerfumes() + viewmodel.insertNoteSortedPerfumes() + assertEquals(viewmodel.perfumesState.value, notePerfumeRecommendationResult) + } + + @Test + fun `test_insertNoteAfterInsertPrice_reflectsInIsEmptyPriceContentNeedState`() { + viewmodel.insertPriceSortedPerfumes() + viewmodel.insertNoteSortedPerfumes() + assertEquals(viewmodel.isEmptyPriceContentNeedState.value, false) + } + + @Test + fun `test_insertPriceAfterInsertNote_reflectsInIsEmptyPriceContentNeedState`() { + viewmodel.insertNoteSortedPerfumes() + viewmodel.insertPriceSortedPerfumes() + assertEquals(viewmodel.isEmptyPriceContentNeedState.value, true) + } +} From 4296f93c0c7323c12b6f324c6c25122e42421281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 19 Nov 2024 16:47:16 +0900 Subject: [PATCH 29/93] =?UTF-8?q?Test:=20=EB=B7=B0=EB=AA=A8=EB=8D=B8=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=EC=82=AC=ED=95=AD=20=EB=B0=98=EC=98=81?= =?UTF-8?q?=ED=95=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hmoa/feature_hbti/HbtiSurveyScreenTest.kt | 8 +++--- .../hmoa/feature_hbti/NotePickScreenTest.kt | 26 +++++++++++-------- .../feature_hbti/HbtiSurveyViewModelTest.kt | 17 +++++++----- .../feature_hbti/NotePickViewmodelTest.kt | 14 ++++++---- 4 files changed, 39 insertions(+), 26 deletions(-) diff --git a/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/HbtiSurveyScreenTest.kt b/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/HbtiSurveyScreenTest.kt index a42757e0e..fbfaf3c26 100644 --- a/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/HbtiSurveyScreenTest.kt +++ b/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/HbtiSurveyScreenTest.kt @@ -6,10 +6,10 @@ import androidx.compose.ui.test.onNodeWithTag import androidx.test.ext.junit.runners.AndroidJUnit4 import com.hmoa.core_common.ErrorMessageType import com.hmoa.core_common.ErrorUiState -import com.hmoa.core_domain.repository.SurveyRepository -import com.hmoa.core_model.data.ErrorMessage import com.hmoa.core_domain.entity.data.HbtiQuestionItem import com.hmoa.core_domain.entity.data.HbtiQuestionItems +import com.hmoa.core_domain.repository.SurveyRepository +import com.hmoa.core_model.data.ErrorMessage import com.hmoa.core_model.request.SurveyRespondRequestDto import com.hmoa.core_model.response.RecommendNotesResponseDto import com.hmoa.feature_hbti.screen.HbtiSurveyScreen @@ -49,7 +49,7 @@ class HbtiSurveyScreenTest : TestCase() { selectedOptionIds = mutableListOf() ) val hbtiData = HbtiSurveyUiState.HbtiData( - hbtiQuestionItems = HbtiQuestionItems(mutableMapOf(0 to hbtiQuestionItem_singleChoice)), + hbtiQuestionItems = HbtiQuestionItems(mutableMapOf(0 to hbtiQuestionItem_singleChoice), questionCounts = 1), hbtiAnswerIds = null, isNextQuestionAvailable = null ) @@ -97,4 +97,4 @@ class HbtiSurveyScreenTest : TestCase() { } composeTestRule.onNodeWithTag("unknownError").assertExists() } -} \ No newline at end of file +} diff --git a/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/NotePickScreenTest.kt b/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/NotePickScreenTest.kt index 5a4d3e2c2..2aa385993 100644 --- a/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/NotePickScreenTest.kt +++ b/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/NotePickScreenTest.kt @@ -5,9 +5,9 @@ import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.onAllNodesWithText import androidx.compose.ui.test.onNodeWithText import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.hmoa.core_domain.entity.data.NoteSelect import com.hmoa.core_domain.repository.HshopRepository import com.hmoa.core_domain.repository.SurveyRepository -import com.hmoa.core_domain.entity.data.NoteSelect import com.hmoa.core_model.response.ProductListResponseDto import com.hmoa.core_model.response.ProductResponseDto import com.hmoa.feature_hbti.screen.NotePickGridWindow @@ -38,42 +38,48 @@ class NotePickScreenTest : TestCase() { productName = "우드", productDetails = "나무 어쩌고저쩌고", productPhotoUrl = "나무사진", - isRecommended = true + isRecommended = true, + price = 1000 ), ProductResponseDto( productId = 1, productName = "프루트", productDetails = "피치,블루베리,블랙체리", productPhotoUrl = "과일사진", - isRecommended = true + isRecommended = true, + price = 1000 ), ProductResponseDto( productId = 2, productName = "아쿠아", productDetails = "씨 솔트", productPhotoUrl = "바다사진", - isRecommended = true + isRecommended = true, + price = 1000 ), ProductResponseDto( productId = 3, productName = "스위트", productDetails = "허니, 바닐라, 프랄린", productPhotoUrl = "꿀사진", - isRecommended = false + isRecommended = false, + price = 1000 ), ProductResponseDto( productId = 4, productName = "스파이스", productDetails = "넛맥, 블랙페퍼", productPhotoUrl = "후추사진", - isRecommended = false + isRecommended = false, + price = 1000 ), ProductResponseDto( productId = 5, productName = "머스크", productDetails = "화이트 머스크, 코튼, 엠버, 벤조인", productPhotoUrl = "카펫사진", - isRecommended = false + isRecommended = false, + price = 1000 ) ) ) @@ -105,14 +111,12 @@ class NotePickScreenTest : TestCase() { composeTestRule.setContent { NotePickGridWindow( notes = notes, - noteOrderQuantity = 5, - selectedNotesOrderQuantity = 3, isNoteSelectedList = isNoteSelectedList, - onClickItem = { index, value, data, noteOrderQuantity, selectedNotesOrderQuantity -> } + onClickItem = { index: Int, value: Boolean, data: NoteSelect -> {} } ) } composeTestRule.onAllNodesWithText("Best!")[0].assertIsDisplayed() composeTestRule.onAllNodesWithText("Best!")[1].assertIsDisplayed() composeTestRule.onNodeWithText("3").assertIsDisplayed() } -} \ No newline at end of file +} diff --git a/feature-hbti/src/test/java/com/hmoa/feature_hbti/HbtiSurveyViewModelTest.kt b/feature-hbti/src/test/java/com/hmoa/feature_hbti/HbtiSurveyViewModelTest.kt index 908e02067..0c8be0f45 100644 --- a/feature-hbti/src/test/java/com/hmoa/feature_hbti/HbtiSurveyViewModelTest.kt +++ b/feature-hbti/src/test/java/com/hmoa/feature_hbti/HbtiSurveyViewModelTest.kt @@ -2,10 +2,10 @@ package com.hmoa.feature_hbti import ResultResponse import com.hmoa.core_common.ErrorMessageType -import com.hmoa.core_domain.repository.SurveyRepository -import com.hmoa.core_model.data.ErrorMessage import com.hmoa.core_domain.entity.data.HbtiQuestionItem import com.hmoa.core_domain.entity.data.HbtiQuestionItems +import com.hmoa.core_domain.repository.SurveyRepository +import com.hmoa.core_model.data.ErrorMessage import com.hmoa.core_model.response.SurveyOptionResponseDto import com.hmoa.core_model.response.SurveyQuestionResponseDto import com.hmoa.core_model.response.SurveyQuestionsResponseDto @@ -89,7 +89,8 @@ class HbtiSurveyViewModelTest : TestCase() { hbtiQuestions = mutableMapOf( 0 to hbtiQuestionItem_singleChoice, 1 to hbtiQuestionItem_multiChoice - ) + ), + questionCounts = 2 ) launch { viewModel.getSurveyQuestions() }.join() assertEquals(expectedValue, viewModel.hbtiQuestionItemsState.value) @@ -244,7 +245,10 @@ class HbtiSurveyViewModelTest : TestCase() { ) ) val expectedValue = - HbtiQuestionItems(hbtiQuestions = mutableMapOf(0 to hbtiQuestionItem_singleChoice, 1 to updatedItem)) + HbtiQuestionItems( + hbtiQuestions = mutableMapOf(0 to hbtiQuestionItem_singleChoice, 1 to updatedItem), + questionCounts = 2 + ) viewModel.getSurveyQuestions() val result = viewModel.getUpdatedHbtiQuestionItems(page = 1, newHbtiQuestionItem = updatedItem) @@ -267,7 +271,8 @@ class HbtiSurveyViewModelTest : TestCase() { hbtiQuestionItem_multiChoice.optionIds[1] ) ) - ) + ), + questionCounts = 2 ) viewModel.getSurveyQuestions() viewModel.modifyAnswersToOptionId( @@ -341,4 +346,4 @@ class HbtiSurveyViewModelTest : TestCase() { ) assertEquals(expectedValue, viewModel.isNextQuestionAvailable.value) } -} \ No newline at end of file +} diff --git a/feature-hbti/src/test/java/com/hmoa/feature_hbti/NotePickViewmodelTest.kt b/feature-hbti/src/test/java/com/hmoa/feature_hbti/NotePickViewmodelTest.kt index e211296cb..bdebaca0a 100644 --- a/feature-hbti/src/test/java/com/hmoa/feature_hbti/NotePickViewmodelTest.kt +++ b/feature-hbti/src/test/java/com/hmoa/feature_hbti/NotePickViewmodelTest.kt @@ -143,7 +143,11 @@ class NotePickViewmodelTest : TestCase() { ) } launch { viewmodel.getNoteProducts() }.join() - launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value) }.join() + launch { + viewmodel.initializeIsNoteSelectedList( + viewmodel.noteProductState.value, + onUpdateProducts = {}) + }.join() Assert.assertEquals(expectedNoteSelectData, viewmodel.isNoteSelectDataState.value) } @@ -151,7 +155,7 @@ class NotePickViewmodelTest : TestCase() { fun `test_1NoteSelect_reflectsInNoteSelectData`() = coroutineRule.runTest { viewmodel.getTopRecommendedNote() launch { viewmodel.getNoteProducts() }.join() - launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value) }.join() + launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value, {}) }.join() val targetNode = noteProducts.data!!.data[0] viewmodel.handleNoteSelectData( index = 0, @@ -258,7 +262,7 @@ class NotePickViewmodelTest : TestCase() { //Given: 초기화 viewmodel.getTopRecommendedNote() launch { viewmodel.getNoteProducts() }.join() - launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value) }.join() + launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value, {}) }.join() //Then: 버튼의 사용가능여부 = false이다 Assert.assertEquals(false, viewmodel.isNextButtonAvailableState.value) } @@ -268,7 +272,7 @@ class NotePickViewmodelTest : TestCase() { //Given: 초기화 viewmodel.getTopRecommendedNote() launch { viewmodel.getNoteProducts() }.join() - launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value) }.join() + launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value, {}) }.join() val targetNode = noteProducts.data!!.data[0] //When:targetNode만 선택한다 viewmodel.handleNoteSelectData( @@ -290,7 +294,7 @@ class NotePickViewmodelTest : TestCase() { //Given: 초기화 후 targetNode만 선택한다 viewmodel.getTopRecommendedNote() launch { viewmodel.getNoteProducts() }.join() - launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value) }.join() + launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value, {}) }.join() val targetNode = noteProducts.data!!.data[0] viewmodel.handleNoteSelectData( index = 0, From 81d2d7270921b94934070a3d3bf6191ac4ef3d9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 19 Nov 2024 17:30:40 +0900 Subject: [PATCH 30/93] =?UTF-8?q?Fix:=20=EB=B8=8C=EB=9E=9C=EB=93=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=82=AD=EC=A0=9C=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../response/BrandDefaultResponseDto.kt | 2 - .../hmoa/feature_brand/screen/BrandScreen.kt | 66 ++++++++----------- .../feature_brand/screen/BrandSearchScreen.kt | 66 +++++-------------- 3 files changed, 43 insertions(+), 91 deletions(-) diff --git a/core-model/src/main/java/com/hmoa/core_model/response/BrandDefaultResponseDto.kt b/core-model/src/main/java/com/hmoa/core_model/response/BrandDefaultResponseDto.kt index 093a08fa8..15ae05bb8 100644 --- a/core-model/src/main/java/com/hmoa/core_model/response/BrandDefaultResponseDto.kt +++ b/core-model/src/main/java/com/hmoa/core_model/response/BrandDefaultResponseDto.kt @@ -4,9 +4,7 @@ import kotlinx.serialization.Serializable @Serializable data class BrandDefaultResponseDto( - val brandId: Int, - val brandImageUrl: String, val brandName: String, val englishName: String ) diff --git a/feature-brand/src/main/java/com/hmoa/feature_brand/screen/BrandScreen.kt b/feature-brand/src/main/java/com/hmoa/feature_brand/screen/BrandScreen.kt index d1602c645..a25a52342 100644 --- a/feature-brand/src/main/java/com/hmoa/feature_brand/screen/BrandScreen.kt +++ b/feature-brand/src/main/java/com/hmoa/feature_brand/screen/BrandScreen.kt @@ -1,17 +1,8 @@ package com.hmoa.feature_brand.screen -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.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxHeight -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.* import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.GridItemSpan import androidx.compose.foundation.lazy.grid.LazyVerticalGrid @@ -24,7 +15,6 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight @@ -35,7 +25,6 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.paging.compose.LazyPagingItems import androidx.paging.compose.collectAsLazyPagingItems import com.hmoa.core_designsystem.R -import com.hmoa.core_designsystem.component.ImageView import com.hmoa.core_designsystem.component.PerfumeWithCountItemView import com.hmoa.core_designsystem.component.TopBar import com.hmoa.core_designsystem.theme.CustomColor @@ -147,7 +136,7 @@ fun BrandContent( } @Composable -fun BrandView(koreanTitle: String, englishTitle: String, imageUrl: String) { +fun BrandView(koreanTitle: String, englishTitle: String) { Column( modifier = Modifier.height(200.dp).background(Color.Black).padding(16.dp).fillMaxWidth(), verticalArrangement = Arrangement.SpaceBetween @@ -156,33 +145,23 @@ fun BrandView(koreanTitle: String, englishTitle: String, imageUrl: String) { Text( text = englishTitle, modifier = Modifier.fillMaxWidth(), - style = TextStyle(fontWeight = FontWeight.Medium, fontSize = 14.sp, color = Color.White, fontFamily = CustomFont.regular) + style = TextStyle( + fontWeight = FontWeight.Medium, + fontSize = 14.sp, + color = Color.White, + fontFamily = CustomFont.regular + ) ) Text( text = koreanTitle, modifier = Modifier.fillMaxWidth(), - style = TextStyle(fontWeight = FontWeight.Medium, fontSize = 14.sp, color = Color.White, fontFamily = CustomFont.regular) - ) - } - Column( - horizontalAlignment = Alignment.End, - verticalArrangement = Arrangement.Bottom, - modifier = Modifier.fillMaxWidth().background(Color.Black) - ) { - Column( - modifier = Modifier.border(BorderStroke(width = 2.dp, color = CustomColor.gray3)) - .width(100.dp).height(100.dp).background(Color.White), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Bottom, - ) { - ImageView( - imageUrl, - width = 0.9f, - height = 1f, - backgroundColor = Color.White, - contentScale = ContentScale.FillWidth, + style = TextStyle( + fontWeight = FontWeight.Medium, + fontSize = 14.sp, + color = Color.White, + fontFamily = CustomFont.regular ) - } + ) } } } @@ -208,7 +187,6 @@ fun PerfumeGridView( BrandView( koreanTitle = brandData?.brandName ?: "", englishTitle = brandData?.englishName ?: "", - imageUrl = brandData?.brandImageUrl ?: "" ) Row( modifier = Modifier.fillMaxWidth().padding(16.dp), @@ -217,13 +195,21 @@ fun PerfumeGridView( ) { Text( "좋아요순", - style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.Light, fontFamily = CustomFont.regular), + style = TextStyle( + fontSize = 12.sp, + fontWeight = FontWeight.Light, + fontFamily = CustomFont.regular + ), modifier = Modifier.padding(end = 4.dp).clickable { onSortLikeClick() }, color = likeColor ) Text( "최신순", - style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.Light, fontFamily = CustomFont.regular), + style = TextStyle( + fontSize = 12.sp, + fontWeight = FontWeight.Light, + fontFamily = CustomFont.regular + ), modifier = Modifier.clickable { onSortLatestClick() }, color = latestColor ) @@ -253,7 +239,7 @@ fun PerfumeGridView( @Preview fun BrandContentPreview() { Column { - BrandView("조말론 런던", "JO MALONE LONDON", "") + BrandView("조말론 런던", "JO MALONE LONDON") Row { PerfumeWithCountItemView( imageUrl = "", @@ -283,4 +269,4 @@ fun BrandContentPreview() { ) } } -} \ No newline at end of file +} diff --git a/feature-brand/src/main/java/com/hmoa/feature_brand/screen/BrandSearchScreen.kt b/feature-brand/src/main/java/com/hmoa/feature_brand/screen/BrandSearchScreen.kt index e16d8560e..ff93f382e 100644 --- a/feature-brand/src/main/java/com/hmoa/feature_brand/screen/BrandSearchScreen.kt +++ b/feature-brand/src/main/java/com/hmoa/feature_brand/screen/BrandSearchScreen.kt @@ -1,46 +1,26 @@ package com.hmoa.feature_brand.screen -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.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.aspectRatio -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.requiredSize -import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.* import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.TextUnitType import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel -import com.hmoa.core_designsystem.component.ImageView import com.hmoa.core_designsystem.component.SearchTopBar +import com.hmoa.core_designsystem.component.TagBadge import com.hmoa.core_designsystem.component.TypeBadge import com.hmoa.core_designsystem.theme.CustomColor -import com.hmoa.core_designsystem.theme.CustomFont import com.hmoa.core_domain.entity.data.Consonant import com.hmoa.core_model.response.BrandDefaultResponseDto import com.hmoa.feature_brand.viewmodel.BrandSearchViewmodel @@ -181,31 +161,19 @@ fun BrandItem(brand: BrandDefaultResponseDto?, onBrandClick: (brandId: Int) -> U verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { - Column( - modifier = Modifier.border(BorderStroke(width = 2.dp, color = CustomColor.gray9)) - .width(size).aspectRatio(1f).background(Color.White), - horizontalAlignment = Alignment.CenterHorizontally - ) { - ImageView( - imageUrl = brand?.brandImageUrl ?: "", - width = 0.9f, - height = 1f, - backgroundColor = Color.White, - contentScale = ContentScale.FillWidth - ) - } - Text( - text = brand?.brandName ?: "", - style = TextStyle( - fontWeight = FontWeight.Light, - fontSize = 14.sp, - color = Color.Black, - textAlign = TextAlign.Start, - fontFamily = CustomFont.regular - ), - modifier = Modifier.width(size), - overflow = TextOverflow.Ellipsis, - maxLines = 2 - ) + TagBadge(tag = brand?.brandName ?: "") +// Text( +// text = brand?.brandName ?: "", +// style = TextStyle( +// fontWeight = FontWeight.Light, +// fontSize = 14.sp, +// color = Color.Black, +// textAlign = TextAlign.Start, +// fontFamily = CustomFont.regular +// ), +// modifier = Modifier.width(size), +// overflow = TextOverflow.Ellipsis, +// maxLines = 2 +// ) } -} \ No newline at end of file +} From 706377ab2536129ec809b663d08907119d8fe1e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 19 Nov 2024 17:39:56 +0900 Subject: [PATCH 31/93] =?UTF-8?q?Design:=20=EC=83=81=EB=8B=A8=20=EB=B0=94?= =?UTF-8?q?=20=ED=8C=A8=EB=94=A9=20=EB=B6=88=EC=9D=BC=EC=B9=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hmoa/feature_hbti/screen/HbtiScreen.kt | 265 +++++++++--------- 1 file changed, 134 insertions(+), 131 deletions(-) diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiScreen.kt index 84b4b2a49..968f8f298 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiScreen.kt @@ -206,7 +206,6 @@ private fun HbtiHomeContent( LazyColumn( modifier = Modifier .fillMaxSize() - .padding(horizontal = 16.dp) ) { item { Column { @@ -218,169 +217,173 @@ private fun HbtiHomeContent( onNavClick = onBackClick, navIconColor = Color.White ) - Text( - "당신의 향BTI는 무엇일까요?", - style = TextStyle( - color = Color.White, - fontWeight = FontWeight.Bold, - fontFamily = pretendard, - fontSize = 20.sp - ), - modifier = Modifier.padding(top = 20.dp, bottom = 12.dp) - ) - Text( - "검사를 통해 좋아하는 향료와\n향수까지 알아보세요!", - style = TextStyle( - color = Color.White, - fontWeight = FontWeight.Normal, - fontFamily = pretendard, - fontSize = 14.sp + Column(Modifier.padding(horizontal = 16.dp)) { + Text( + "당신의 향BTI는 무엇일까요?", + style = TextStyle( + color = Color.White, + fontWeight = FontWeight.Bold, + fontFamily = pretendard, + fontSize = 20.sp + ), + modifier = Modifier.padding(top = 20.dp, bottom = 12.dp) ) - ) - Row(modifier = Modifier.padding(top = 20.dp, bottom = 32.dp)) { - Box( - Modifier - .padding(end = 15.dp) - .fillMaxWidth(0.5f) - .height(107.dp) - .clickable { onHbtiSurveyClick() } - .background( - color = Color.Transparent, - shape = RoundedCornerShape(5.dp) - )) { - ImageView( - imageUrl = metadata?.firstImageUrl, - width = 1f, - height = 1f, - backgroundColor = Color.Transparent, - contentScale = ContentScale.FillBounds + Text( + "검사를 통해 좋아하는 향료와\n향수까지 알아보세요!", + style = TextStyle( + color = Color.White, + fontWeight = FontWeight.Normal, + fontFamily = pretendard, + fontSize = 14.sp ) - Column( + ) + Row(modifier = Modifier.padding(top = 20.dp, bottom = 32.dp)) { + Box( + Modifier + .padding(end = 15.dp) + .fillMaxWidth(0.5f) + .height(107.dp) + .clickable { onHbtiSurveyClick() } + .background( + color = Color.Transparent, + shape = RoundedCornerShape(5.dp) + )) { + ImageView( + imageUrl = metadata?.firstImageUrl, + width = 1f, + height = 1f, + backgroundColor = Color.Transparent, + contentScale = ContentScale.FillBounds + ) + Column( + modifier = Modifier + .fillMaxWidth(1f) + .height(107.dp) + ) { + Text( + "향BTI\n검사하러 가기", + style = TextStyle( + color = Color.Black, + fontWeight = FontWeight.Bold, + fontFamily = pretendard, + fontSize = 16.sp + ), + modifier = Modifier.padding(20.dp) + ) + } + } + Box( modifier = Modifier .fillMaxWidth(1f) .height(107.dp) + .background( + color = Color.Transparent, + shape = RoundedCornerShape(5.dp) + ) + .clickable { onAfterOrderClick() } + .background( + color = Color.Transparent, + shape = RoundedCornerShape(5.dp) + ) ) { - Text( - "향BTI\n검사하러 가기", - style = TextStyle( - color = Color.Black, - fontWeight = FontWeight.Bold, - fontFamily = pretendard, - fontSize = 16.sp - ), - modifier = Modifier.padding(20.dp) + ImageView( + imageUrl = metadata?.secondImageUrl, + width = 1f, + height = 1f, + backgroundColor = Color.Transparent, + contentScale = ContentScale.FillBounds ) + Column( + modifier = Modifier + .fillMaxWidth(1f) + .height(107.dp) + ) { + Text( + "향료 입력하기\n(주문 후)", + style = TextStyle( + color = Color.Black, + fontWeight = FontWeight.Bold, + fontFamily = pretendard, + fontSize = 16.sp + ), + modifier = Modifier.padding(20.dp) + ) + } } } - Box( + Row( + verticalAlignment = Alignment.CenterVertically, modifier = Modifier - .fillMaxWidth(1f) - .height(107.dp) - .background( - color = Color.Transparent, - shape = RoundedCornerShape(5.dp) - ) - .clickable { onAfterOrderClick() } + .height(30.dp) .background( color = Color.Transparent, shape = RoundedCornerShape(5.dp) ) ) { ImageView( - imageUrl = metadata?.secondImageUrl, - width = 1f, + imageUrl = "https://github.com/HMOAA/HMOA_ANDROID/assets/67788699/eb5499d5-25e4-4141-af66-353daa76f2a2", + width = 0.1f, height = 1f, backgroundColor = Color.Transparent, - contentScale = ContentScale.FillBounds + contentScale = ContentScale.FillHeight ) - Column( - modifier = Modifier - .fillMaxWidth(1f) - .height(107.dp) + Spacer(Modifier.width(9.dp)) + Text( + "향BTI 후기", + style = TextStyle( + color = Color.White, + fontWeight = FontWeight.Bold, + fontFamily = pretendard, + fontSize = 20.sp + ) + ) + } + Row( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 12.dp), + horizontalArrangement = Arrangement.End + ) { + TextButton( + onClick = onReviewItemClick ) { Text( - "향료 입력하기\n(주문 후)", + "전체보기", style = TextStyle( - color = Color.Black, + color = Color.White, fontWeight = FontWeight.Bold, fontFamily = pretendard, - fontSize = 16.sp + fontSize = 12.sp ), - modifier = Modifier.padding(20.dp) ) } } } - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .height(30.dp) - .background( - color = Color.Transparent, - shape = RoundedCornerShape(5.dp) - ) - ) { - ImageView( - imageUrl = "https://github.com/HMOAA/HMOA_ANDROID/assets/67788699/eb5499d5-25e4-4141-af66-353daa76f2a2", - width = 0.1f, - height = 1f, - backgroundColor = Color.Transparent, - contentScale = ContentScale.FillHeight - ) - Spacer(Modifier.width(9.dp)) - Text( - "향BTI 후기", - style = TextStyle( - color = Color.White, - fontWeight = FontWeight.Bold, - fontFamily = pretendard, - fontSize = 20.sp - ) - ) - } - Row( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 12.dp), - horizontalArrangement = Arrangement.End - ) { - TextButton( - onClick = onReviewItemClick - ) { - Text( - "전체보기", - style = TextStyle( - color = Color.White, - fontWeight = FontWeight.Bold, - fontFamily = pretendard, - fontSize = 12.sp - ), - ) - } - } } } items(reviews) { review -> val images = remember(review.hbtiPhotos) { review.hbtiPhotos.map { it.photoUrl } } - ReviewItem( - isItemClickable = true, - reviewId = review.hbtiReviewId, - profileImg = review.profileImgUrl, - nickname = review.author, - writtenAt = review.createdAt, - isLiked = review.isLiked, - heartNumber = review.heartCount, - content = review.content, - images = images, - category = review.orderTitle, - onHeartClick = onHeartClick, - onMenuClick = { - selectedReview = review - dialogOpen() - }, - onItemClick = onReviewItemClick - ) - Spacer(Modifier.height(12.dp)) + Column(Modifier.padding(horizontal = 16.dp)) { + ReviewItem( + isItemClickable = true, + reviewId = review.hbtiReviewId, + profileImg = review.profileImgUrl, + nickname = review.author, + writtenAt = review.createdAt, + isLiked = review.isLiked, + heartNumber = review.heartCount, + content = review.content, + images = images, + category = review.orderTitle, + onHeartClick = onHeartClick, + onMenuClick = { + selectedReview = review + dialogOpen() + }, + onItemClick = onReviewItemClick + ) + Spacer(Modifier.height(12.dp)) + } } } } From d308d8eb79da62b7d948ba5fe5b5cea9de84d5dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 19 Nov 2024 17:49:21 +0900 Subject: [PATCH 32/93] =?UTF-8?q?Fix:=20=ED=96=A5=EC=88=98=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=EC=9D=98=20=EB=B8=8C=EB=9E=9C=EB=93=9C=20=EC=82=AC?= =?UTF-8?q?=EC=A7=84=20=EC=82=AD=EC=A0=9C=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hmoa/core_domain/entity/data/Perfume.kt | 1 - .../core_domain/usecase/GetPerfumeUsecase.kt | 5 +- .../response/PerfumeDetailResponseDto.kt | 1 - .../feature_perfume/screen/PerfumeScreen.kt | 83 ++++++++++--------- 4 files changed, 46 insertions(+), 44 deletions(-) diff --git a/core-domain/src/main/java/com/hmoa/core_domain/entity/data/Perfume.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/Perfume.kt index bb11a523a..dc0d55d2c 100644 --- a/core-domain/src/main/java/com/hmoa/core_domain/entity/data/Perfume.kt +++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/Perfume.kt @@ -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-domain/src/main/java/com/hmoa/core_domain/usecase/GetPerfumeUsecase.kt b/core-domain/src/main/java/com/hmoa/core_domain/usecase/GetPerfumeUsecase.kt index d1c271310..9e86964d4 100644 --- a/core-domain/src/main/java/com/hmoa/core_domain/usecase/GetPerfumeUsecase.kt +++ b/core-domain/src/main/java/com/hmoa/core_domain/usecase/GetPerfumeUsecase.kt @@ -2,9 +2,9 @@ package com.hmoa.core_domain.usecase import ResultResponse import com.hmoa.core_domain.emitOrThrow +import com.hmoa.core_domain.entity.data.Perfume import com.hmoa.core_domain.repository.PerfumeRepository import com.hmoa.core_model.data.ErrorMessage -import com.hmoa.core_domain.entity.data.Perfume import com.hmoa.core_model.response.PerfumeCommentGetResponseDto import com.hmoa.core_model.response.PerfumeCommentResponseDto import com.hmoa.core_model.response.PerfumeDetailResponseDto @@ -25,7 +25,6 @@ class GetPerfumeUsecase @Inject constructor( brandEnglishName = perfumeInfo1.data?.brandEnglishName ?: "", brandKoreanName = perfumeInfo1.data?.brandName ?: "", brandId = perfumeInfo1.data?.brandId.toString(), - brandImgUrl = perfumeInfo1.data?.brandImgUrl ?: "", perfumeEnglishName = perfumeInfo1.data?.englishName ?: "", perfumeKoreanName = perfumeInfo1.data?.koreanName ?: "", baseNote = perfumeInfo1.data?.baseNote ?: "", @@ -162,4 +161,4 @@ enum class TastingNoteImageUrl(val index: Int, val imageUrl: String) { index = 17, imageUrl = "https://github.com/HMOAA/HMOA_ANDROID/assets/67788699/6c5d2111-737f-48bb-b480-5ad883b120c9" ), -} \ No newline at end of file +} diff --git a/core-model/src/main/java/com/hmoa/core_model/response/PerfumeDetailResponseDto.kt b/core-model/src/main/java/com/hmoa/core_model/response/PerfumeDetailResponseDto.kt index 237ffd213..a0889fad1 100644 --- a/core-model/src/main/java/com/hmoa/core_model/response/PerfumeDetailResponseDto.kt +++ b/core-model/src/main/java/com/hmoa/core_model/response/PerfumeDetailResponseDto.kt @@ -7,7 +7,6 @@ data class PerfumeDetailResponseDto( val baseNote: String?, val brandEnglishName: String, val brandId: Int, - val brandImgUrl: String, val brandName: String, val englishName: String, val heartNote: String?, diff --git a/feature-perfume/src/main/java/com/hmoa/feature_perfume/screen/PerfumeScreen.kt b/feature-perfume/src/main/java/com/hmoa/feature_perfume/screen/PerfumeScreen.kt index f7ec610bd..0cdb323f7 100644 --- a/feature-perfume/src/main/java/com/hmoa/feature_perfume/screen/PerfumeScreen.kt +++ b/feature-perfume/src/main/java/com/hmoa/feature_perfume/screen/PerfumeScreen.kt @@ -5,8 +5,6 @@ import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ModalBottomSheetLayout import androidx.compose.material.ModalBottomSheetValue @@ -28,17 +26,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.hmoa.core_designsystem.component.AppLoadingScreen -import com.hmoa.core_designsystem.component.Button -import com.hmoa.core_designsystem.component.CommentItem -import com.hmoa.core_designsystem.component.CustomSlider -import com.hmoa.core_designsystem.component.ErrorUiSetView -import com.hmoa.core_designsystem.component.ImageView -import com.hmoa.core_designsystem.component.PerfumeItemView -import com.hmoa.core_designsystem.component.ReportModal -import com.hmoa.core_designsystem.component.TopBar -import com.hmoa.core_designsystem.component.TypeBadge -import com.hmoa.core_designsystem.component.VoteView +import com.hmoa.core_designsystem.component.* import com.hmoa.core_designsystem.theme.CustomColor import com.hmoa.core_designsystem.theme.CustomFont import com.hmoa.core_domain.entity.data.Perfume @@ -249,7 +237,7 @@ fun PerfumeContent( modifier = Modifier.clickable { onBrandClick(data.brandId) }.padding(horizontal = 16.dp) .padding(top = 48.dp) ) { - BrandCard(data.brandImgUrl, data.brandEnglishName, data.brandKoreanName) + BrandCard(data.brandEnglishName, data.brandKoreanName) } TastingNoteView( notes = arrayOf(data.topNote ?: "", data.heartNote ?: "", data.baseNote ?: ""), @@ -287,7 +275,11 @@ fun PerfumeContent( ) Text( "같은 브랜드의 제품", - style = TextStyle(fontSize = 20.sp, fontWeight = FontWeight.Medium, fontFamily = CustomFont.regular), + style = TextStyle( + fontSize = 20.sp, + fontWeight = FontWeight.Medium, + fontFamily = CustomFont.regular + ), modifier = Modifier.padding(end = 4.dp).padding(top = 40.dp) ) Spacer( @@ -382,21 +374,9 @@ fun PerfumeVolumeView(volume: Int, color: Color) { } @Composable -fun BrandCard(imageUrl: String, brandEnglishName: String?, brandKoreanName: String) { +fun BrandCard(brandEnglishName: String?, brandKoreanName: String) { Row(modifier = Modifier.border(border = BorderStroke(width = 1.dp, color = CustomColor.gray3))) { - Column( - modifier = Modifier.width(68.dp).height(68.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center - ) { - ImageView( - imageUrl = imageUrl, - backgroundColor = Color.White, - width = 0.9f, - height = 1f, - contentScale = ContentScale.FillWidth - ) - } + Column( modifier = Modifier.fillMaxWidth().height(68.dp).background(color = Color.Black).padding(start = 10.dp), verticalArrangement = Arrangement.Center @@ -449,7 +429,11 @@ fun TastingNoteView(notes: Array, imageUrls: List, noteTitle: Li ) Text( notes[index], - style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.Medium, fontFamily = CustomFont.regular), + style = TextStyle( + fontSize = 12.sp, + fontWeight = FontWeight.Medium, + fontFamily = CustomFont.regular + ), modifier = Modifier.padding(start = 8.dp) ) } @@ -500,8 +484,10 @@ fun PerfumeWeathernessView(onWeatherClick: (value: Weather) -> Unit, weatherData ) } Text( - "여러분의 생각을 투표해주세요", style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.Medium, fontFamily = CustomFont.regular), - modifier = Modifier.padding(vertical = 20.dp).fillMaxWidth(), textAlign = TextAlign.End + "여러분의 생각을 투표해주세요", + style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.Medium, fontFamily = CustomFont.regular), + modifier = Modifier.padding(vertical = 20.dp).fillMaxWidth(), + textAlign = TextAlign.End ) } @@ -537,8 +523,10 @@ fun PerfumeGenderView(onGenderClick: (value: PerfumeGender) -> Unit, genderData: ) } Text( - "여러분의 생각을 투표해주세요", style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.Medium, fontFamily = CustomFont.regular), - modifier = Modifier.padding(vertical = 20.dp).fillMaxWidth(), textAlign = TextAlign.End + "여러분의 생각을 투표해주세요", + style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.Medium, fontFamily = CustomFont.regular), + modifier = Modifier.padding(vertical = 20.dp).fillMaxWidth(), + textAlign = TextAlign.End ) } @@ -569,17 +557,24 @@ fun PerfumeAgeView( horizontalArrangement = Arrangement.SpaceBetween ) { Text( - "10대", style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Normal, fontFamily = CustomFont.regular), + "10대", + style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Normal, fontFamily = CustomFont.regular), modifier = Modifier.padding(11.dp) ) if (ageData?.writed == true) { Text( - "평균 ${ageData.age}세", style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Normal, fontFamily = CustomFont.regular), + "평균 ${ageData.age}세", + style = TextStyle( + fontSize = 16.sp, + fontWeight = FontWeight.Normal, + fontFamily = CustomFont.regular + ), modifier = Modifier.padding(11.dp) ) } Text( - "50대 이상", style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Normal, fontFamily = CustomFont.regular) + "50대 이상", + style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Normal, fontFamily = CustomFont.regular) ) } } @@ -611,7 +606,12 @@ fun CommentView( if (commentCount == 0) { Text( "해당 제품에 대한 의견을 남겨주세요", - style = TextStyle(fontSize = 14.sp, fontWeight = FontWeight.Medium, color = CustomColor.gray3, fontFamily = CustomFont.regular), + style = TextStyle( + fontSize = 14.sp, + fontWeight = FontWeight.Medium, + color = CustomColor.gray3, + fontFamily = CustomFont.regular + ), modifier = Modifier.fillMaxWidth().padding(vertical = 52.dp), textAlign = TextAlign.Center ) @@ -685,7 +685,12 @@ fun BottomToolBar(isLiked: Boolean, onLikeClick: (value: Boolean) -> Unit, onCom Text( "댓글작성", modifier = Modifier.padding(start = 8.dp), - style = TextStyle(fontWeight = FontWeight.Medium, fontSize = 16.sp, color = Color.White, fontFamily = CustomFont.regular) + style = TextStyle( + fontWeight = FontWeight.Medium, + fontSize = 16.sp, + color = Color.White, + fontFamily = CustomFont.regular + ) ) } } From fe16e40b1168737046dcf6832fc44b2ac004bfcb Mon Sep 17 00:00:00 2001 From: Lee YongIn <67788699+LeeYongIn0517@users.noreply.github.com> Date: Tue, 19 Nov 2024 17:50:28 +0900 Subject: [PATCH 33/93] =?UTF-8?q?Feature/hbti=20HBTI=20=EB=94=94=EC=9E=90?= =?UTF-8?q?=EC=9D=B8=20=EC=B5=9C=EC=A2=85=20=EC=88=98=EC=A0=95=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=20(#184)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Design: 공백 수정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Release 1.0.0(18) 출시 (#147) * Feature-Magazine Init * Chore: Manifest 정리 * Chore: 기본 의존성 설정 * Chore: Test 관련 의존성 정리 * Chore: Compose 설정 * Feat: Response Dto 추가 * Feat: Magazine Screen 추가 * Feat: Magazine Service 추가 * Feat: Magazine Service DI 추가 * Resource: Floating Action Button Open Icon 추가 * Feat: Magazine DataStore 추가 * Fix: Response 타입 수정 * Feat: Data Store DI * Feat: Repository DI * Feat: Magazine Repository 추가 * Feat: 최신 향수 받아오는 API 추가 * Feat: 최신 향수 받아오는 DTO 추가 * Resource: 공유 아이콘 추가 * Feat: Magazine ViewModel 로직 추가 * Design: TopBar 투명도 파라미터 추가 * Rename: 파일 명 변경 * Design: 투명도 추가 * Design: Magazine Tag 추가 * Resource: 아이콘 resource 추가 * Fix: Response 타입 변경 * Chore: Magazine 의존성 추가 * Feat: Magazine Navigation 추가 * Fix: Bottom Navigation 내용 변경 * Feat: Magazine 상세 화면 추가 * Feat: Magazine Paging 추가 * Feat: Magazine Route 클래스 추가 * Feat: Magazine 상세 비즈니스 로직 추가 * Fix: Conflict 수정 * Fix: Paging 오류 수정 * Design: title 색상 파라미터 추가 * Design: title 색상 파라미터 추가 * Design: review content 위치 변경 * Design: Content 글자 수 제한 * Design: title 글자 수 제한 * Fix: 개행문자 수정 * Feat: Navigation 이벤트 추가 * Feat: Magazine 상세 화면 추가 * Feat: Magazine 상세 화면 비즈니스 로직 추가 * Feat: Navigation 이벤트 추가 * Fix: 데이터 순서에 따른 오류 수정 * Design: Tag UI 수정 * Design: Space 크기 조절 * Feat: 좋아요 update 이벤트 추가 * Fix: Navigation 이벤트 파라미터 추가 * Feat: Navigation 이벤트 파라미터 추가 * Design: Magazine UI 위치 수정 * Fix: Magazine Image 추가 * Resource: Magazine Icon 추가 * Design: 바텀 네비게이션 UI 수정 * Feat: Navigation SingleTop 옵션 추가 * Feat: 좋아요 한 향수 페이지 위치 변동 * FIX: 비로그인 에러다이얼로그 동작 오류 수정 * Fix: Navigation 누락 오류 수정 * Fix: err state 누락 오류 수정 * Fix: navigation 누락 수정 * Design: UI 간격 수정 * Gradle: Material 의존성 추가 * Design: 수정 모달 추가 * Refactor: Dialog 팝업 방식 변경 * FIX: 좋아요 리프레싱 시 리컴포지션 안되는 오류 수정 * Rename: 이름 혼동 방지 * Rename: 이름 혼동 방지 * Fix: Dialog Pop up 시 깜빡거림 수정 * Feat: 향수페이지 댓글 오류 수정 * Fix: 향수 페이지 댓글 상태관리 변화 오류 수정 * Delete: 사용하지 않는 상태관리 변수 삭제 * Update README.md * Resource: Font 추가 * Create android.yml develop 브랜치로 코드 푸시, PR 시 빌드되는 기능 * Feat: 자동 빌드 기능 테스트 구문 * Update android.yml * Feat: 자바 버전 11 -> 17 * Fix: CI환경 빌드에 local.properties 파일 동적 생성 기능 추가 * Fix: 경로 오류 수정 * Feat: 모든 모듈의 local-properties파일 삭제 명령파일 생성 * Fix: app 모듈왜 local.properties를 사용하는 모듈도 파일 동적생성 적용 * Chore: 서브 모듈 추가 * Delete: mylibrary 모듈 삭제 * Chore: AndroidSecretSecure 서브 레포지토리 추가 * Revert "Delete: mylibrary 모듈 삭제" This reverts commit cc0c0fd6d21b7f3d941ed11ab515ff2bf6b8e8ab. * Revert "Chore: 서브 모듈 추가" This reverts commit 95cc85845823843a72eb29a6b65a001b99947c6f. * Fix: 소셜 토큰 api 호출 오류 수정 * Ignore * Fix: lateinit 삭제 및 초기화 값 지정 * Fix: IndexOutOfBoundException방지 구문 추가 * Chore: google-service.json 파일 추가 * Rename * Chore: NATIVE_APP_KEY 적용 * Chore: 버전 증가 6->7 * Feat: 토큰 유무 검사 로직 수정 * Feat: 토큰 가져오는 비동기 작업 -> 동기로 변경 * Fix: 토큰 갱신 작업 대기방식을 동기적으로 변경 * Fix: 스트림 닫힘 오류 원인 부분 해결 * Revert "Feat: 토큰 가져오는 비동기 작업 -> 동기로 변경" This reverts commit f56f46f1000603260a6f143dd4304ffc1b4750bf. * Fix: postFcmToken NullPointException 원인구문 삭제 * Fix: 인터셉터 토큰 추가동작 수정 비동기 -> 동기 * Chore: v1.0.0 버전코드 수정 (7->8) * Fix: native app key, string value로 변경 * Fix: HttpLoggingInterceptor 제거 - IllgalStateException 해결을 위해 지워봄 * Refactor: HPediaDesc api호출 분리 및 CastException 해결 * Chore: 버전코드 수정(8->9) * Chore: 버전코드 수정 (9->10) * Fix: 변수 명 오류 * Chore: 버전코드 수정(10->11) * Fix: 카카오 앱 키 참조 방식 변경 * Chore: 버전코드 수정(11->12) * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Chore: core-common 의존성 추가 * Delete: 토큰 재발급 임시 로직 삭제 * HotFix: Authenticator 토큰 재발급 및 에러메세지 전달 기능 수정 * Fix: Authenticator 적용 * Fix: api 호출부에 Authenticator 적용 * Delete: 안쓰는 api 삭제 * Refactor: FCM 초기화 및 초기 라우팅 코드 함수로 분리 * Delete: 임시 refreshToken 코드 관련 api 삭제 * Rename: 토큰 관련 클래스 의존성 주입 모듈 이름 수정 * Fix: 토큰 동적 할당 시점 변경 * Fix: 로그인 화면 이동 네비게이션 변경 * Chore: 버전 변경 (v1.1.1 -> v1.1.2) * Chore: ci,cd 구문 변경 및 action.yml 파일 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: ci/cd 워크플로우 임시로 주석처리 및 사용중지 * Chore: android.yml 워크플로우 일시중지 (#164) * Chore: CI 구문 롤백 및 오작동 CI/CD 임시폴더로 분리 * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 * v1.1.1 버전 master로 머지합니다 (#163) * Feat: Fcm 관련 함수 추가 * Chore: FCM 모듈 의존성 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Chore: fcm 모듈 환경 설정 추가 * Feat: App Navigation 이벤트 추가 * Chore: FCM 모듈 환경 설정 * Resource: 아이콘 추가 * Feat: 알림 수신 여부 이벤트 추가 * Feat: 알림 화면 추가 * Feat: 알림 화면 비즈니스 로직 추가 * Feat: FCM 모듈 추가 * Feat: 알림 Response 모델 추가 * Feat: 알림 화면 네비게이션 추가 * Design: 읽음 여부에 따른 배경색 조절 * Test: 테스트 코드 추가 * Feat: App Scheme 추가 * Feat: Deeplink Navigation 추가 * Ignore * Delete: sample-app 모듈 삭제 * Delete: Hhmoa_android_secret 로컬 폴더 삭제 * Design: Button 컴포넌트 disabled color 이름 적용 * Feat: Hbti설문 아이템 컴포넌트 추가 * Feat: ProgressBar 컴포넌트 생성 * Feat: VerticalStepBar 컴포넌트 생성 * Design: 홈화면 상단 로고 아이콘 추가 * Design: 디자인시스템 모듈 내 컴포넌트에 pretendard 폰트 적용 * Feat: profile 속성 추가 * Feat: send top notification 파라미터 수정 * Feat: profile 속성 추가 * Chore: Activity single top 속성 설정 * Fix: Error Ui State 업데이트 안되는 오류 수정 * Feat: deeplink 처리 함수 추가 * Refactor: Community, HPedia 네비게이션 분리 * Refactor: Community, HPedia 네비게이션 분리 * Feat: deeplink 설정 * Fix: 경로 설정 오류 수정 * Fix: deeplink 위치 오류 수정 * Fix: Response Dto 형식 오류 수정 * Design: Profile 반영 * Feat: 선택 이벤트 추가 * Feat: Navigation 설정 * Feat: 읽음 처리 함수 추가 * Fix: read 변경 가능하도록 수정 * Test: import 수정 * ignore: git pull * Design: 색상 변경 * Feat: NoteImageItem 생성 * Feat: 권한 설정 여부 정보를 확인 * Feat: 권한 설정 함수 추가 * Ignore * Ignore * Feat: feature-hbti 모듈 생성 * Feat:선택지 무효화 기능 추가 및 SurveyOptionList로 수정 * Rename: SurveyOptionItem -> SurveyOptionList * Feat: ProgressBarPreview에 +/- 효과 추가 * Chore: gradle 의존성 추가 * Fix: intent 이름 변경 * Feat: 알림 선택 시 읽음 처리 이벤트 추가 * Feat: 포그라운드 알림 처리 * Fix: Navigation Deeplink 오류 수정 * Chore: mockito 라이브러리 추가 * Feat: HbtiScreen 추가 * Chore: compose material 및 preview 라이브러리 추가 * Feat: Hbti화면 완성 * Design: 향BTI 화면 디자인 구성 완료 * Feat: 향BTI 테스트 데이터계층 클래스 생성 * Rename: SurveyAnswerResponseDto -> SurveyOptionResponseDto * Feat: fcm token 저장 함수 추가 * Fix: 파라미터 이름 오류 수정 * Fix: 토큰 저장 알고리즘 수정 * Feat: 향수 추천 화면 추가 * Design: 공백 수정 * Feat: 데이터 계층 hilt 주입코드 추가 * Feat: HbtiSurvey 화면 추가(미완성) * Feat: 가격 선택 화면 추가 * Design: 아이템 간 간격 조절 * Rename: 컴포넌트 이름 변경 * Rename: 컴포넌트 이름 변경 * Feat: 향료 선택 화면 추가 * Refactor: 화면 구성 변경 * Fix: 파라미터 변경 * Resource: icon 추가 * Fix: 파라미터 수정 * Feat: 향료 선택 화면 추가 * Style: 공백 스타일 변경 * Fix: 푸쉬 오류 수정 * Style: 코드 스타일 변경 * Feat: 향수 추천 결과 화면 추가 * Rename: 컴포넌트 이름 변경 * Ignore * Delete * Chore: test 라이브러리 추가 * Feat: HbtiSurveyViewmodel 생성 * Test: HbtiSurveyViewModel 테스트 생성 * Test: 테스트 기대값 수정 * Feat: Dto 추가 * Feat: Api 추가 * Style: 코드 라인 변경 * Feat: 비즈니스 로직 추가 * Remove: 삭제 * Feat: 향료 데이터 클래스 추가 * Comment: 주석 추가 * Fix: 서버에 정보 전달 로직 임의 대체 * Rename: 함수 명 변경 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: UI 상태 기준 분기 * Feat: Navigation 설정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: android.yml 워크플로우 일시중지 (#164) * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Fix: 파라미터 명시적으로 구분 * Fix: RouteScreen 파라미터 변수명 변경 반영 * Chore: 버전코드 수정 22->23 * Ignore * Fix: 백업데이터 설정 해제 * Chore: 버전 업데이트 * Release 1.1.2버전 master로 푸시 (#167) * Feat: Fcm 관련 함수 추가 * Chore: FCM 모듈 의존성 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Chore: fcm 모듈 환경 설정 추가 * Feat: App Navigation 이벤트 추가 * Chore: FCM 모듈 환경 설정 * Resource: 아이콘 추가 * Feat: 알림 수신 여부 이벤트 추가 * Feat: 알림 화면 추가 * Feat: 알림 화면 비즈니스 로직 추가 * Feat: FCM 모듈 추가 * Feat: 알림 Response 모델 추가 * Feat: 알림 화면 네비게이션 추가 * Design: 읽음 여부에 따른 배경색 조절 * Test: 테스트 코드 추가 * Feat: App Scheme 추가 * Feat: Deeplink Navigation 추가 * Ignore * Delete: sample-app 모듈 삭제 * Delete: Hhmoa_android_secret 로컬 폴더 삭제 * Design: Button 컴포넌트 disabled color 이름 적용 * Feat: Hbti설문 아이템 컴포넌트 추가 * Feat: ProgressBar 컴포넌트 생성 * Feat: VerticalStepBar 컴포넌트 생성 * Design: 홈화면 상단 로고 아이콘 추가 * Design: 디자인시스템 모듈 내 컴포넌트에 pretendard 폰트 적용 * Feat: profile 속성 추가 * Feat: send top notification 파라미터 수정 * Feat: profile 속성 추가 * Chore: Activity single top 속성 설정 * Fix: Error Ui State 업데이트 안되는 오류 수정 * Feat: deeplink 처리 함수 추가 * Refactor: Community, HPedia 네비게이션 분리 * Refactor: Community, HPedia 네비게이션 분리 * Feat: deeplink 설정 * Fix: 경로 설정 오류 수정 * Fix: deeplink 위치 오류 수정 * Fix: Response Dto 형식 오류 수정 * Design: Profile 반영 * Feat: 선택 이벤트 추가 * Feat: Navigation 설정 * Feat: 읽음 처리 함수 추가 * Fix: read 변경 가능하도록 수정 * Test: import 수정 * ignore: git pull * Design: 색상 변경 * Feat: NoteImageItem 생성 * Feat: 권한 설정 여부 정보를 확인 * Feat: 권한 설정 함수 추가 * Ignore * Ignore * Feat: feature-hbti 모듈 생성 * Feat:선택지 무효화 기능 추가 및 SurveyOptionList로 수정 * Rename: SurveyOptionItem -> SurveyOptionList * Feat: ProgressBarPreview에 +/- 효과 추가 * Chore: gradle 의존성 추가 * Fix: intent 이름 변경 * Feat: 알림 선택 시 읽음 처리 이벤트 추가 * Feat: 포그라운드 알림 처리 * Fix: Navigation Deeplink 오류 수정 * Chore: mockito 라이브러리 추가 * Feat: HbtiScreen 추가 * Chore: compose material 및 preview 라이브러리 추가 * Feat: Hbti화면 완성 * Design: 향BTI 화면 디자인 구성 완료 * Feat: 향BTI 테스트 데이터계층 클래스 생성 * Rename: SurveyAnswerResponseDto -> SurveyOptionResponseDto * Feat: fcm token 저장 함수 추가 * Fix: 파라미터 이름 오류 수정 * Fix: 토큰 저장 알고리즘 수정 * Feat: 향수 추천 화면 추가 * Design: 공백 수정 * Feat: 데이터 계층 hilt 주입코드 추가 * Feat: HbtiSurvey 화면 추가(미완성) * Feat: 가격 선택 화면 추가 * Design: 아이템 간 간격 조절 * Rename: 컴포넌트 이름 변경 * Rename: 컴포넌트 이름 변경 * Feat: 향료 선택 화면 추가 * Refactor: 화면 구성 변경 * Fix: 파라미터 변경 * Resource: icon 추가 * Fix: 파라미터 수정 * Feat: 향료 선택 화면 추가 * Style: 공백 스타일 변경 * Fix: 푸쉬 오류 수정 * Style: 코드 스타일 변경 * Feat: 향수 추천 결과 화면 추가 * Rename: 컴포넌트 이름 변경 * Ignore * Delete * Chore: test 라이브러리 추가 * Feat: HbtiSurveyViewmodel 생성 * Test: HbtiSurveyViewModel 테스트 생성 * Test: 테스트 기대값 수정 * Feat: Dto 추가 * Feat: Api 추가 * Style: 코드 라인 변경 * Feat: 비즈니스 로직 추가 * Remove: 삭제 * Feat: 향료 데이터 클래스 추가 * Comment: 주석 추가 * Fix: 서버에 정보 전달 로직 임의 대체 * Rename: 함수 명 변경 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: UI 상태 기준 분기 * Feat: Navigation 설정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: android.yml 워크플로우 일시중지 (#164) * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Revert "Chore: 버전 업데이트" This reverts commit 031fc2f141d3ffbc07b0954eda874c58d7e1c834. * Revert "Fix: 백업데이터 설정 해제" This reverts commit bb68a8d265be89d74bcc2feed66baca5355cd475. * HotFix: 카카오 sdk 버전 업그레이드 * HotFix: 카카오 sdk 버전 업그레이드 (#170) * HotFix: 카카오 sdk 버전 업그레이드 * Feat: gradlew clean 작업 추가 * Delete * Delete: refreshToken 추상메서드 삭제 * Delete: 토큰 리프레싱 임시방안 코드 삭제 * HotFix: 카카오 sdk 버전 업그레이드 (#174) * Hotfix/community (#176) * Fix: 좋아요 반영 안되는 오류 수정 * Fix: response에 wrapping 추가 * Design: 내용 및 사진 누락 추가 * Fix: response wrapping * Design: 디자인 누락 추가 * Refactor: 불필요 로직 삭제 * Feat: 파라미터 명 변경 * Design: 버튼 가려지는 현상 수정 * Fix: hbti 향료개수 자유선택 후 튕기는 현상 수정 * Fix: hbti 향료 선택결과 제출로직 변경 * Fix: hbti 향료선택화면 하단버튼 disabled 상태관리 추가 * Fix: hbti 향료 카테고리 선택화면 로직 변경 반영 * Test: hbti 향료 카테고리 선택화면 로직 변경사항 테스트 * Design: 백버튼 추가 * Feat: 향료 제품 가격 추가 * Refactor: 플래그 제거 및 콜백으로 대체 * Design: 디자인 마진 변경 * Design: Topbar 배경 수정 * Feat: hbti 홈화면 메타데이터 추가 및 기존 데이터 리팩토링 * Design: 홈 디자인 변경 반영 * Design: Topbar 디폴트 배경 변경 * Feat: 로그인 유무 확인 코드 추가 * Design: 스크롤 초기 위치 수정 * Chore: 버전 코드 변경 (24 -> 25) * Design: 향모아 사업자 정보 추가 * Fix: hbti 메타데이터 요청 오류 임시 주석처리 * Chore: 데이터백업설정 변경 * Chore: 테스트 버전 업그레이드 25->27 * chore: gitignore 파일 추가 * chore: 주석해제 * Feat: 상품 구매 여부 확인 다이얼로그 추가 * Feat: Hbti 설문 양옆 스크롤 기능 추가 * Delete: 주석 삭제 * Fix: LazyColumn으로 변경 후 스크롤위치 초기화 적용 * Refactor: isNoteSelectedData상태 업데이트 함수 수정 * fix: Hbti ProgressBar 리컴포지션 최적화 및 UI 버그 개선 * Design: Hbti 향료 선택화면 디테일 변경 * Fix: nullable 처리 누락 수정 * Feat: 향료주문 과정 설명 화면 api 적용 * Feat: 향료주문 과정 설명 화면 네비게이션 추가 * Feat: 가격대 향수추천 결과 화면 추가 * Test: 향수 추천결과 화면 UI/단위 테스트 작성 * Test: 뷰모델 변경사항 반영한 테스트 수정 * Fix: 브랜드 이미지 삭제 반영 * Design: 상단 바 패딩 불일치 수정 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> --- .../java/com/hmoa/app/navigation/NavHost.kt | 82 +----- .../Hshop/HshopRemoteDataStore.kt | 9 +- .../Hshop/HshopRemoteDataStoreImpl.kt | 53 ++-- .../component/VerticalStepBar.kt | 15 +- .../core_domain/repository/HshopRepository.kt | 9 +- .../response/BrandDefaultResponseDto.kt | 2 - .../response/ContentAndTitleResponse.kt | 9 + .../response/OrderDescriptionResponseDto.kt | 9 + .../hmoa/core_network/service/HshopService.kt | 23 +- .../core_repository/HshopRepositoryImpl.kt | 16 +- .../hmoa/feature_brand/screen/BrandScreen.kt | 66 ++--- .../feature_brand/screen/BrandSearchScreen.kt | 66 ++--- feature-hbti/build.gradle.kts | 2 +- .../hmoa/feature_hbti/HbtiSurveyScreenTest.kt | 8 +- .../hmoa/feature_hbti/NotePickScreenTest.kt | 26 +- .../PerfumeRecommendationResultScreenTest.kt | 30 ++ .../feature_hbti/navigation/HbtiNavigation.kt | 28 +- .../feature_hbti/screen/HbtiProcessScreen.kt | 122 ++++++-- .../hmoa/feature_hbti/screen/HbtiScreen.kt | 265 +++++++++--------- .../PerfumeRecommendationResultScreen.kt | 83 ++++-- .../viewmodel/HbtiProcessViewmodel.kt | 104 +++++++ .../PerfumeRecommendationResultViewModel.kt | 25 +- .../feature_hbti/HbtiSurveyViewModelTest.kt | 17 +- .../feature_hbti/NotePickViewmodelTest.kt | 14 +- ...erfumeRecommendationResultViewmodelTest.kt | 74 +++++ 25 files changed, 716 insertions(+), 441 deletions(-) create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/ContentAndTitleResponse.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/OrderDescriptionResponseDto.kt create mode 100644 feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/PerfumeRecommendationResultScreenTest.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiProcessViewmodel.kt create mode 100644 feature-hbti/src/test/java/com/hmoa/feature_hbti/PerfumeRecommendationResultViewmodelTest.kt 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 fef5d6235..8c5150beb 100644 --- a/app/src/main/java/com/hmoa/app/navigation/NavHost.kt +++ b/app/src/main/java/com/hmoa/app/navigation/NavHost.kt @@ -3,61 +3,14 @@ package com.hmoa.app.navigation import androidx.compose.runtime.Composable import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost -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_authentication.navigation.* 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.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_community.Navigation.* import com.hmoa.feature_fcm.alarmRoute -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_hbti.navigation.* +import com.hmoa.feature_home.navigation.* import com.hmoa.feature_hpedia.Navigation.navigateToHPedia import com.hmoa.feature_hpedia.Navigation.navigateToHPediaDescRoute import com.hmoa.feature_hpedia.Navigation.navigateToHPediaSearchRoute @@ -65,30 +18,8 @@ import com.hmoa.feature_hpedia.Navigation.nestedHPediaGraph 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.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 +import com.hmoa.feature_perfume.navigation.* +import com.hmoa.feature_userinfo.navigation.* @Composable fun SetUpNavGraph( @@ -262,6 +193,7 @@ fun SetUpNavGraph( onBackClick = navController::navigateToBack, ) hbtiProcessScreen( + navLogin = navController::navigateToLogin, onBackClick = navController::navigateToBack, onNextClick = navController::navigateToNotePick ) 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 18fb5cf1c..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,11 +2,7 @@ package com.hmoa.core_datastore.Hshop import ResultResponse import com.hmoa.core_model.request.ProductListRequestDto -import com.hmoa.core_model.response.FinalOrderResponseDto -import com.hmoa.core_model.response.GetMyOrderResponseDto -import com.hmoa.core_model.response.PostNoteOrderResponseDto -import com.hmoa.core_model.response.PostNoteSelectedResponseDto -import com.hmoa.core_model.response.ProductListResponseDto +import com.hmoa.core_model.response.* interface HshopRemoteDataStore { suspend fun getCart(): ResultResponse @@ -16,4 +12,5 @@ interface HshopRemoteDataStore { suspend fun getFinalOrderResult(orderId: Int): ResultResponse suspend fun deleteNoteInOrder(orderId: Int, productId: Int): ResultResponse suspend fun getMyOrders(): ResultResponse> -} \ No newline at end of file + 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 e54901f79..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 @@ -3,29 +3,29 @@ 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.FinalOrderResponseDto -import com.hmoa.core_model.response.GetMyOrderResponseDto -import com.hmoa.core_model.response.PostNoteOrderResponseDto -import com.hmoa.core_model.response.PostNoteSelectedResponseDto -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.decodeFromString import kotlinx.serialization.json.Json import javax.inject.Inject -class HshopRemoteDataStoreImpl @Inject constructor(private val hshopService: HshopService) : HshopRemoteDataStore { +class HshopRemoteDataStoreImpl @Inject constructor( + private val hshopService: HshopService, + private val authenticator: Authenticator +) : HshopRemoteDataStore { override suspend fun getCart(): ResultResponse { val result = ResultResponse() - hshopService.getCart().suspendOnSuccess{ + hshopService.getCart().suspendOnSuccess { result.data = this.data - }.suspendOnError{ + }.suspendOnError { result.errorMessage = Json.decodeFromString(this.message()) } return result } + override suspend fun getNotes(): ResultResponse { var result = ResultResponse() hshopService.getNotes().suspendOnSuccess { @@ -39,9 +39,9 @@ class HshopRemoteDataStoreImpl @Inject constructor(private val hshopService: Hsh override suspend fun postNoteOrder(dto: ProductListRequestDto): ResultResponse { val result = ResultResponse() - hshopService.postNoteOrder(dto).suspendOnSuccess{ + hshopService.postNoteOrder(dto).suspendOnSuccess { result.data = this.data - }.suspendOnError{ + }.suspendOnError { result.errorMessage = Json.decodeFromString(this.message()) } return result @@ -57,11 +57,12 @@ class HshopRemoteDataStoreImpl @Inject constructor(private val hshopService: Hsh } return result } + override suspend fun getFinalOrderResult(orderId: Int): ResultResponse { val result = ResultResponse() - hshopService.getFinalOrderResult(orderId).suspendOnSuccess{ + hshopService.getFinalOrderResult(orderId).suspendOnSuccess { result.data = this.data - }.suspendOnError{ + }.suspendOnError { result.errorMessage = Json.decodeFromString(this.message()) } return result @@ -72,20 +73,36 @@ class HshopRemoteDataStoreImpl @Inject constructor(private val hshopService: Hsh productId: Int ): ResultResponse { val result = ResultResponse() - hshopService.deleteNoteInOrder(orderId, productId).suspendOnSuccess{ + hshopService.deleteNoteInOrder(orderId, productId).suspendOnSuccess { result.data = this.data - }.suspendOnError{ + }.suspendOnError { result.errorMessage = Json.decodeFromString(this.message()) } return result } + override suspend fun getMyOrders(): ResultResponse> { val result = ResultResponse>() - hshopService.getMyOrders().suspendOnError{ + hshopService.getMyOrders().suspendOnError { result.errorMessage = Json.decodeFromString(this.message()) - }.suspendOnSuccess{ + }.suspendOnSuccess { result.data = this.data } return result } -} \ No newline at end of file + + 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.getOrderDescriptions().suspendOnSuccess { result.data = this.data } + }) + } + return result + } +} 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-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 d0d22f7f8..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,11 +2,7 @@ package com.hmoa.core_domain.repository import ResultResponse import com.hmoa.core_model.request.ProductListRequestDto -import com.hmoa.core_model.response.FinalOrderResponseDto -import com.hmoa.core_model.response.GetMyOrderResponseDto -import com.hmoa.core_model.response.PostNoteOrderResponseDto -import com.hmoa.core_model.response.PostNoteSelectedResponseDto -import com.hmoa.core_model.response.ProductListResponseDto +import com.hmoa.core_model.response.* interface HshopRepository { suspend fun getCart(): ResultResponse @@ -16,4 +12,5 @@ interface HshopRepository { suspend fun getFinalOrderResult(orderId: Int): ResultResponse suspend fun deleteNoteInOrder(orderId: Int, productId: Int): ResultResponse suspend fun getMyOrders(): ResultResponse> -} \ No newline at end of file + suspend fun getOrderDescriptions(): ResultResponse +} diff --git a/core-model/src/main/java/com/hmoa/core_model/response/BrandDefaultResponseDto.kt b/core-model/src/main/java/com/hmoa/core_model/response/BrandDefaultResponseDto.kt index 093a08fa8..15ae05bb8 100644 --- a/core-model/src/main/java/com/hmoa/core_model/response/BrandDefaultResponseDto.kt +++ b/core-model/src/main/java/com/hmoa/core_model/response/BrandDefaultResponseDto.kt @@ -4,9 +4,7 @@ import kotlinx.serialization.Serializable @Serializable data class BrandDefaultResponseDto( - val brandId: Int, - val brandImageUrl: String, val brandName: String, val englishName: String ) diff --git a/core-model/src/main/java/com/hmoa/core_model/response/ContentAndTitleResponse.kt b/core-model/src/main/java/com/hmoa/core_model/response/ContentAndTitleResponse.kt new file mode 100644 index 000000000..fa6d908b2 --- /dev/null +++ b/core-model/src/main/java/com/hmoa/core_model/response/ContentAndTitleResponse.kt @@ -0,0 +1,9 @@ +package com.hmoa.core_model.response + +import kotlinx.serialization.Serializable + +@Serializable +data class ContentAndTitle( + val content: String, + val title: String +) diff --git a/core-model/src/main/java/com/hmoa/core_model/response/OrderDescriptionResponseDto.kt b/core-model/src/main/java/com/hmoa/core_model/response/OrderDescriptionResponseDto.kt new file mode 100644 index 000000000..bd7b32da8 --- /dev/null +++ b/core-model/src/main/java/com/hmoa/core_model/response/OrderDescriptionResponseDto.kt @@ -0,0 +1,9 @@ +package com.hmoa.core_model.response + +import kotlinx.serialization.Serializable + +@Serializable +data class OrderDescriptionResponseDto( + val orderDescriptionImgUrl: String, + val orderDescriptions: List +) diff --git a/core-network/src/main/java/com/hmoa/core_network/service/HshopService.kt b/core-network/src/main/java/com/hmoa/core_network/service/HshopService.kt index 0a72d6d97..fc1b3db84 100644 --- a/core-network/src/main/java/com/hmoa/core_network/service/HshopService.kt +++ b/core-network/src/main/java/com/hmoa/core_network/service/HshopService.kt @@ -1,36 +1,37 @@ package com.hmoa.core_network.service import com.hmoa.core_model.request.ProductListRequestDto -import com.hmoa.core_model.response.FinalOrderResponseDto -import com.hmoa.core_model.response.GetMyOrderResponseDto -import com.hmoa.core_model.response.PostNoteOrderResponseDto -import com.hmoa.core_model.response.PostNoteSelectedResponseDto -import com.hmoa.core_model.response.ProductListResponseDto +import com.hmoa.core_model.response.* import com.skydoves.sandwich.ApiResponse -import retrofit2.http.Body -import retrofit2.http.DELETE -import retrofit2.http.GET -import retrofit2.http.POST -import retrofit2.http.Path +import retrofit2.http.* interface HshopService { @GET("/shop/cart") suspend fun getCart(): ApiResponse + @GET("/shop/note") suspend fun getNotes(): ApiResponse + @POST("/shop/note/order") suspend fun postNoteOrder(@Body dto: ProductListRequestDto): ApiResponse + @POST("/shop/note/select") suspend fun postNotesSelected(@Body dto: ProductListRequestDto): ApiResponse + @GET("/shop/note/order/{orderId}") suspend fun getFinalOrderResult( @Path("orderId") orderId: Int ): ApiResponse + @DELETE("/shop/note/order/{orderId}/product/{productId}") suspend fun deleteNoteInOrder( @Path("orderId") orderId: Int, @Path("productId") productId: Int ): ApiResponse + @GET("/shop/order/me") suspend fun getMyOrders(): ApiResponse> -} \ No newline at end of file + + @GET("/shop/order/description") + suspend fun getOrderDescriptions(): ApiResponse +} diff --git a/core-repository/src/main/java/com/hmoa/core_repository/HshopRepositoryImpl.kt b/core-repository/src/main/java/com/hmoa/core_repository/HshopRepositoryImpl.kt index c97c8e53f..c5a407d8a 100644 --- a/core-repository/src/main/java/com/hmoa/core_repository/HshopRepositoryImpl.kt +++ b/core-repository/src/main/java/com/hmoa/core_repository/HshopRepositoryImpl.kt @@ -4,11 +4,7 @@ import ResultResponse import com.hmoa.core_datastore.Hshop.HshopRemoteDataStore import com.hmoa.core_domain.repository.HshopRepository import com.hmoa.core_model.request.ProductListRequestDto -import com.hmoa.core_model.response.FinalOrderResponseDto -import com.hmoa.core_model.response.GetMyOrderResponseDto -import com.hmoa.core_model.response.PostNoteOrderResponseDto -import com.hmoa.core_model.response.PostNoteSelectedResponseDto -import com.hmoa.core_model.response.ProductListResponseDto +import com.hmoa.core_model.response.* import javax.inject.Inject class HshopRepositoryImpl @Inject constructor(private val hshopRemoteDataStore: HshopRemoteDataStore) : @@ -16,6 +12,7 @@ class HshopRepositoryImpl @Inject constructor(private val hshopRemoteDataStore: override suspend fun getCart(): ResultResponse { return hshopRemoteDataStore.getCart() } + override suspend fun getNotesProduct(): ResultResponse { return hshopRemoteDataStore.getNotes() } @@ -23,9 +20,11 @@ class HshopRepositoryImpl @Inject constructor(private val hshopRemoteDataStore: override suspend fun postNoteOrder(dto: ProductListRequestDto): ResultResponse { return hshopRemoteDataStore.postNoteOrder(dto) } + override suspend fun postNotesSelected(dto: ProductListRequestDto): ResultResponse { return hshopRemoteDataStore.postNotesSelected(dto) } + override suspend fun getFinalOrderResult(orderId: Int): ResultResponse { return hshopRemoteDataStore.getFinalOrderResult(orderId) } @@ -36,7 +35,12 @@ class HshopRepositoryImpl @Inject constructor(private val hshopRemoteDataStore: ): ResultResponse { return hshopRemoteDataStore.deleteNoteInOrder(orderId, productId) } + override suspend fun getMyOrders(): ResultResponse> { return hshopRemoteDataStore.getMyOrders() } -} \ No newline at end of file + + override suspend fun getOrderDescriptions(): ResultResponse { + return hshopRemoteDataStore.getOrderDescriptions() + } +} diff --git a/feature-brand/src/main/java/com/hmoa/feature_brand/screen/BrandScreen.kt b/feature-brand/src/main/java/com/hmoa/feature_brand/screen/BrandScreen.kt index d1602c645..a25a52342 100644 --- a/feature-brand/src/main/java/com/hmoa/feature_brand/screen/BrandScreen.kt +++ b/feature-brand/src/main/java/com/hmoa/feature_brand/screen/BrandScreen.kt @@ -1,17 +1,8 @@ package com.hmoa.feature_brand.screen -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.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxHeight -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.* import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.GridItemSpan import androidx.compose.foundation.lazy.grid.LazyVerticalGrid @@ -24,7 +15,6 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight @@ -35,7 +25,6 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.paging.compose.LazyPagingItems import androidx.paging.compose.collectAsLazyPagingItems import com.hmoa.core_designsystem.R -import com.hmoa.core_designsystem.component.ImageView import com.hmoa.core_designsystem.component.PerfumeWithCountItemView import com.hmoa.core_designsystem.component.TopBar import com.hmoa.core_designsystem.theme.CustomColor @@ -147,7 +136,7 @@ fun BrandContent( } @Composable -fun BrandView(koreanTitle: String, englishTitle: String, imageUrl: String) { +fun BrandView(koreanTitle: String, englishTitle: String) { Column( modifier = Modifier.height(200.dp).background(Color.Black).padding(16.dp).fillMaxWidth(), verticalArrangement = Arrangement.SpaceBetween @@ -156,33 +145,23 @@ fun BrandView(koreanTitle: String, englishTitle: String, imageUrl: String) { Text( text = englishTitle, modifier = Modifier.fillMaxWidth(), - style = TextStyle(fontWeight = FontWeight.Medium, fontSize = 14.sp, color = Color.White, fontFamily = CustomFont.regular) + style = TextStyle( + fontWeight = FontWeight.Medium, + fontSize = 14.sp, + color = Color.White, + fontFamily = CustomFont.regular + ) ) Text( text = koreanTitle, modifier = Modifier.fillMaxWidth(), - style = TextStyle(fontWeight = FontWeight.Medium, fontSize = 14.sp, color = Color.White, fontFamily = CustomFont.regular) - ) - } - Column( - horizontalAlignment = Alignment.End, - verticalArrangement = Arrangement.Bottom, - modifier = Modifier.fillMaxWidth().background(Color.Black) - ) { - Column( - modifier = Modifier.border(BorderStroke(width = 2.dp, color = CustomColor.gray3)) - .width(100.dp).height(100.dp).background(Color.White), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Bottom, - ) { - ImageView( - imageUrl, - width = 0.9f, - height = 1f, - backgroundColor = Color.White, - contentScale = ContentScale.FillWidth, + style = TextStyle( + fontWeight = FontWeight.Medium, + fontSize = 14.sp, + color = Color.White, + fontFamily = CustomFont.regular ) - } + ) } } } @@ -208,7 +187,6 @@ fun PerfumeGridView( BrandView( koreanTitle = brandData?.brandName ?: "", englishTitle = brandData?.englishName ?: "", - imageUrl = brandData?.brandImageUrl ?: "" ) Row( modifier = Modifier.fillMaxWidth().padding(16.dp), @@ -217,13 +195,21 @@ fun PerfumeGridView( ) { Text( "좋아요순", - style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.Light, fontFamily = CustomFont.regular), + style = TextStyle( + fontSize = 12.sp, + fontWeight = FontWeight.Light, + fontFamily = CustomFont.regular + ), modifier = Modifier.padding(end = 4.dp).clickable { onSortLikeClick() }, color = likeColor ) Text( "최신순", - style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.Light, fontFamily = CustomFont.regular), + style = TextStyle( + fontSize = 12.sp, + fontWeight = FontWeight.Light, + fontFamily = CustomFont.regular + ), modifier = Modifier.clickable { onSortLatestClick() }, color = latestColor ) @@ -253,7 +239,7 @@ fun PerfumeGridView( @Preview fun BrandContentPreview() { Column { - BrandView("조말론 런던", "JO MALONE LONDON", "") + BrandView("조말론 런던", "JO MALONE LONDON") Row { PerfumeWithCountItemView( imageUrl = "", @@ -283,4 +269,4 @@ fun BrandContentPreview() { ) } } -} \ No newline at end of file +} diff --git a/feature-brand/src/main/java/com/hmoa/feature_brand/screen/BrandSearchScreen.kt b/feature-brand/src/main/java/com/hmoa/feature_brand/screen/BrandSearchScreen.kt index e16d8560e..ff93f382e 100644 --- a/feature-brand/src/main/java/com/hmoa/feature_brand/screen/BrandSearchScreen.kt +++ b/feature-brand/src/main/java/com/hmoa/feature_brand/screen/BrandSearchScreen.kt @@ -1,46 +1,26 @@ package com.hmoa.feature_brand.screen -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.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.aspectRatio -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.requiredSize -import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.* import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.TextUnitType import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel -import com.hmoa.core_designsystem.component.ImageView import com.hmoa.core_designsystem.component.SearchTopBar +import com.hmoa.core_designsystem.component.TagBadge import com.hmoa.core_designsystem.component.TypeBadge import com.hmoa.core_designsystem.theme.CustomColor -import com.hmoa.core_designsystem.theme.CustomFont import com.hmoa.core_domain.entity.data.Consonant import com.hmoa.core_model.response.BrandDefaultResponseDto import com.hmoa.feature_brand.viewmodel.BrandSearchViewmodel @@ -181,31 +161,19 @@ fun BrandItem(brand: BrandDefaultResponseDto?, onBrandClick: (brandId: Int) -> U verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { - Column( - modifier = Modifier.border(BorderStroke(width = 2.dp, color = CustomColor.gray9)) - .width(size).aspectRatio(1f).background(Color.White), - horizontalAlignment = Alignment.CenterHorizontally - ) { - ImageView( - imageUrl = brand?.brandImageUrl ?: "", - width = 0.9f, - height = 1f, - backgroundColor = Color.White, - contentScale = ContentScale.FillWidth - ) - } - Text( - text = brand?.brandName ?: "", - style = TextStyle( - fontWeight = FontWeight.Light, - fontSize = 14.sp, - color = Color.Black, - textAlign = TextAlign.Start, - fontFamily = CustomFont.regular - ), - modifier = Modifier.width(size), - overflow = TextOverflow.Ellipsis, - maxLines = 2 - ) + TagBadge(tag = brand?.brandName ?: "") +// Text( +// text = brand?.brandName ?: "", +// style = TextStyle( +// fontWeight = FontWeight.Light, +// fontSize = 14.sp, +// color = Color.Black, +// textAlign = TextAlign.Start, +// fontFamily = CustomFont.regular +// ), +// modifier = Modifier.width(size), +// overflow = TextOverflow.Ellipsis, +// maxLines = 2 +// ) } -} \ No newline at end of file +} diff --git a/feature-hbti/build.gradle.kts b/feature-hbti/build.gradle.kts index c8697ed63..331c6caca 100644 --- a/feature-hbti/build.gradle.kts +++ b/feature-hbti/build.gradle.kts @@ -117,4 +117,4 @@ dependencies { androidTestImplementation("com.google.dagger:hilt-android-testing:$hilt_version") // ...with Kotlin. kaptAndroidTest("com.google.dagger:hilt-android-compiler:$hilt_version") -} \ No newline at end of file +} diff --git a/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/HbtiSurveyScreenTest.kt b/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/HbtiSurveyScreenTest.kt index a42757e0e..fbfaf3c26 100644 --- a/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/HbtiSurveyScreenTest.kt +++ b/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/HbtiSurveyScreenTest.kt @@ -6,10 +6,10 @@ import androidx.compose.ui.test.onNodeWithTag import androidx.test.ext.junit.runners.AndroidJUnit4 import com.hmoa.core_common.ErrorMessageType import com.hmoa.core_common.ErrorUiState -import com.hmoa.core_domain.repository.SurveyRepository -import com.hmoa.core_model.data.ErrorMessage import com.hmoa.core_domain.entity.data.HbtiQuestionItem import com.hmoa.core_domain.entity.data.HbtiQuestionItems +import com.hmoa.core_domain.repository.SurveyRepository +import com.hmoa.core_model.data.ErrorMessage import com.hmoa.core_model.request.SurveyRespondRequestDto import com.hmoa.core_model.response.RecommendNotesResponseDto import com.hmoa.feature_hbti.screen.HbtiSurveyScreen @@ -49,7 +49,7 @@ class HbtiSurveyScreenTest : TestCase() { selectedOptionIds = mutableListOf() ) val hbtiData = HbtiSurveyUiState.HbtiData( - hbtiQuestionItems = HbtiQuestionItems(mutableMapOf(0 to hbtiQuestionItem_singleChoice)), + hbtiQuestionItems = HbtiQuestionItems(mutableMapOf(0 to hbtiQuestionItem_singleChoice), questionCounts = 1), hbtiAnswerIds = null, isNextQuestionAvailable = null ) @@ -97,4 +97,4 @@ class HbtiSurveyScreenTest : TestCase() { } composeTestRule.onNodeWithTag("unknownError").assertExists() } -} \ No newline at end of file +} diff --git a/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/NotePickScreenTest.kt b/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/NotePickScreenTest.kt index 5a4d3e2c2..2aa385993 100644 --- a/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/NotePickScreenTest.kt +++ b/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/NotePickScreenTest.kt @@ -5,9 +5,9 @@ import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.onAllNodesWithText import androidx.compose.ui.test.onNodeWithText import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.hmoa.core_domain.entity.data.NoteSelect import com.hmoa.core_domain.repository.HshopRepository import com.hmoa.core_domain.repository.SurveyRepository -import com.hmoa.core_domain.entity.data.NoteSelect import com.hmoa.core_model.response.ProductListResponseDto import com.hmoa.core_model.response.ProductResponseDto import com.hmoa.feature_hbti.screen.NotePickGridWindow @@ -38,42 +38,48 @@ class NotePickScreenTest : TestCase() { productName = "우드", productDetails = "나무 어쩌고저쩌고", productPhotoUrl = "나무사진", - isRecommended = true + isRecommended = true, + price = 1000 ), ProductResponseDto( productId = 1, productName = "프루트", productDetails = "피치,블루베리,블랙체리", productPhotoUrl = "과일사진", - isRecommended = true + isRecommended = true, + price = 1000 ), ProductResponseDto( productId = 2, productName = "아쿠아", productDetails = "씨 솔트", productPhotoUrl = "바다사진", - isRecommended = true + isRecommended = true, + price = 1000 ), ProductResponseDto( productId = 3, productName = "스위트", productDetails = "허니, 바닐라, 프랄린", productPhotoUrl = "꿀사진", - isRecommended = false + isRecommended = false, + price = 1000 ), ProductResponseDto( productId = 4, productName = "스파이스", productDetails = "넛맥, 블랙페퍼", productPhotoUrl = "후추사진", - isRecommended = false + isRecommended = false, + price = 1000 ), ProductResponseDto( productId = 5, productName = "머스크", productDetails = "화이트 머스크, 코튼, 엠버, 벤조인", productPhotoUrl = "카펫사진", - isRecommended = false + isRecommended = false, + price = 1000 ) ) ) @@ -105,14 +111,12 @@ class NotePickScreenTest : TestCase() { composeTestRule.setContent { NotePickGridWindow( notes = notes, - noteOrderQuantity = 5, - selectedNotesOrderQuantity = 3, isNoteSelectedList = isNoteSelectedList, - onClickItem = { index, value, data, noteOrderQuantity, selectedNotesOrderQuantity -> } + onClickItem = { index: Int, value: Boolean, data: NoteSelect -> {} } ) } composeTestRule.onAllNodesWithText("Best!")[0].assertIsDisplayed() composeTestRule.onAllNodesWithText("Best!")[1].assertIsDisplayed() composeTestRule.onNodeWithText("3").assertIsDisplayed() } -} \ No newline at end of file +} diff --git a/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/PerfumeRecommendationResultScreenTest.kt b/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/PerfumeRecommendationResultScreenTest.kt new file mode 100644 index 000000000..6d9cfac89 --- /dev/null +++ b/feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/PerfumeRecommendationResultScreenTest.kt @@ -0,0 +1,30 @@ +package com.hmoa.feature_hbti + +import androidx.compose.ui.test.junit4.createComposeRule +import com.hmoa.feature_hbti.screen.PerfumeCommentResultContent +import org.junit.Rule +import org.junit.Test + +class PerfumeRecommendationResultScreenTest { + @get:Rule(order = 0) + val composeTestRule = createComposeRule() + + @Test + fun test_EmptyPriceRecommendation_ShowsEmptyResultInfoScreen() { + composeTestRule.setContent { + PerfumeCommentResultContent( + perfumes = emptyList(), + isPriceSortedSelected = true, + isNoteSortedSelected = false, + isEmptyPriceContentNeedState = true, + onClickButton = {}, + onClickPriceSorted = {}, + onClickNoteSorted = {}, + navBack = {}, + navPerfume = {} + ) + } + Thread.sleep(4000) + } + +} diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/navigation/HbtiNavigation.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/navigation/HbtiNavigation.kt index e8e0b3807..42fb13ae1 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/navigation/HbtiNavigation.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/navigation/HbtiNavigation.kt @@ -10,13 +10,13 @@ import com.hmoa.core_domain.entity.navigation.HbtiRoute import com.hmoa.core_domain.entity.navigation.HomeRoute import com.hmoa.core_model.data.NoteProductIds import com.hmoa.feature_hbti.screen.* -import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json fun NavController.navigateToHbti() = navigate("${HbtiRoute.Hbti}") { - popUpTo(HomeRoute.Home.name){inclusive = false} + popUpTo(HomeRoute.Home.name) { inclusive = false } launchSingleTop = true } + fun NavController.navigateToHbtiSurvey() = navigate("${HbtiRoute.HbtiSurvey}") { launchSingleTop = true } fun NavController.navigateToHbtiSurveyResult() = navigate("${HbtiRoute.HbtiSurveyResult}") { launchSingleTop = true } @@ -129,9 +129,10 @@ fun NavGraphBuilder.hbtiSurveyResultScreen( } } -fun NavGraphBuilder.hbtiProcessScreen(onBackClick: () -> Unit, onNextClick: () -> Unit) { +fun NavGraphBuilder.hbtiProcessScreen(navLogin: () -> Unit, onBackClick: () -> Unit, onNextClick: () -> Unit) { composable(route = "${HbtiRoute.HbtiProcess}") { HbtiProcessRoute( + navLogin = navLogin, onBackClick = { onBackClick() }, onNextClick = { onNextClick() }) } @@ -196,6 +197,7 @@ fun NavGraphBuilder.perfumeRecommendationResultRoute( ) } } + fun NavGraphBuilder.order( navBack: () -> Unit, navAddAddress: (String, String) -> Unit, @@ -237,8 +239,8 @@ fun NavGraphBuilder.addAddress( } } -fun NavGraphBuilder.orderResult(navHbti: () -> Unit){ - composable(route = HbtiRoute.OrderResultRoute.name){ +fun NavGraphBuilder.orderResult(navHbti: () -> Unit) { + composable(route = HbtiRoute.OrderResultRoute.name) { OrderResultRoute(navHbti = navHbti) } } @@ -246,13 +248,13 @@ fun NavGraphBuilder.orderResult(navHbti: () -> Unit){ fun NavGraphBuilder.writeReview( navBack: () -> Unit, navReview: (befRoute: HbtiRoute) -> Unit -){ +) { composable( route = "${HbtiRoute.WriteReviewRoute.name}/{orderId}", arguments = listOf( - navArgument("orderId"){type = NavType.IntType} + navArgument("orderId") { type = NavType.IntType } ) - ){ + ) { val orderId = it.arguments?.getInt("orderId") WriteReviewRoute( orderId = orderId, @@ -267,10 +269,10 @@ fun NavGraphBuilder.review( navEditReview: (Int) -> Unit, navLogin: () -> Unit, navWriteReview: (reviewId: Int) -> Unit -){ +) { composable( route = "${HbtiRoute.ReviewRoute.name}" - ){ + ) { ReviewRoute( navBack = navBack, navEditReview = navEditReview, @@ -280,11 +282,11 @@ fun NavGraphBuilder.review( } } -fun NavGraphBuilder.editReview(navReview: (befRoute: HbtiRoute) -> Unit, navLogin: () -> Unit){ +fun NavGraphBuilder.editReview(navReview: (befRoute: HbtiRoute) -> Unit, navLogin: () -> Unit) { composable( route = "${HbtiRoute.EditReviewRoute.name}/{reviewId}", - arguments = listOf(navArgument("reviewId"){type = NavType.IntType}) - ){ + arguments = listOf(navArgument("reviewId") { type = NavType.IntType }) + ) { val reviewId = it.arguments?.getInt("reviewId") EditReviewRoute( reviewId = reviewId, diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiProcessScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiProcessScreen.kt index 2779fe83f..b12a6be5f 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiProcessScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiProcessScreen.kt @@ -1,49 +1,125 @@ package com.hmoa.feature_hbti.screen +import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.hmoa.core_designsystem.R -import com.hmoa.core_designsystem.component.Button -import com.hmoa.core_designsystem.component.TopBar -import com.hmoa.core_designsystem.component.VerticalStepBar +import com.hmoa.core_designsystem.component.* +import com.hmoa.feature_hbti.viewmodel.HbtiProcessUiState +import com.hmoa.feature_hbti.viewmodel.HbtiProcessViewmodel @Composable -fun HbtiProcessRoute(onBackClick: () -> Unit, onNextClick: () -> Unit) { +fun HbtiProcessRoute(navLogin: () -> Unit, onBackClick: () -> Unit, onNextClick: () -> Unit) { HbtiProcessScreen( + navLogin = navLogin, onBackClick = { onBackClick() }, onNextClick = { onNextClick() }) } @Composable -private fun HbtiProcessScreen(onBackClick: () -> Unit, onNextClick: () -> Unit) { - Column( - modifier = Modifier.fillMaxSize().background(color = Color.White).padding(bottom = 40.dp), - verticalArrangement = Arrangement.SpaceBetween - ) { - Column { - TopBar( - title = "향BTI", - titleColor = Color.Black, - navIcon = painterResource(R.drawable.ic_back), - onNavClick = { onBackClick() } +private fun HbtiProcessScreen( + navLogin: () -> Unit, + onBackClick: () -> Unit, + onNextClick: () -> Unit, + viewModel: HbtiProcessViewmodel = hiltViewModel() +) { + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + val errorState by viewModel.errorUiState.collectAsStateWithLifecycle() + + ErrorUiSetView( + onLoginClick = navLogin, + errorUiState = errorState, + onCloseClick = onBackClick + ) + + when (uiState) { + HbtiProcessUiState.Error -> {} + HbtiProcessUiState.Loading -> { + AppLoadingScreen() + } + + is HbtiProcessUiState.Success -> { + HbtiProcessContent( + onBackClick, + onNextClick, + (uiState as HbtiProcessUiState.Success).titles, + (uiState as HbtiProcessUiState.Success).contents, + (uiState as HbtiProcessUiState.Success).descriptionUrl ) - Column(modifier = Modifier.padding(top = 22.dp).padding(horizontal = 16.dp)) { - VerticalStepBar( - arrayOf("향료 선택", "배송", "향수 추천"), - arrayOf("향BTI 검사 이후 추천하는 향료, 원하는 향료 선택(가격대 상이)", "결제 후 1~2일 내 배송 완료", "시향 후 가장 좋았던 향료 선택, 향수 추천 받기") + } + } + +} + +@OptIn(ExperimentalFoundationApi::class) +@Composable +private fun HbtiProcessContent( + onBackClick: () -> Unit, + onNextClick: () -> Unit, + titles: List, + contents: List, + imgUrl: String, +) { + Box( + modifier = Modifier.fillMaxSize() + .background(color = Color.White).padding(bottom = 40.dp), + ) { + LazyColumn { + stickyHeader { + TopBar( + color = Color.White, + title = "향BTI", + titleColor = Color.Black, + navIcon = painterResource(R.drawable.ic_back), + onNavClick = { onBackClick() } ) } + itemsIndexed(listOf("OrderSteps", "ImgUrl")) { idx, item -> + when (idx) { + 0 -> { + Column(modifier = Modifier.padding(top = 22.dp).padding(horizontal = 16.dp)) { + VerticalStepBar( + titles = titles, + contents = contents + ) + } + } + + 1 -> { + Column(modifier = Modifier.padding(top = 17.dp).padding(horizontal = 22.dp)) { + ImageView( + imageUrl = imgUrl, + backgroundColor = Color.White, + contentScale = ContentScale.Inside, + width = 1f, + height = 1f + ) + } + } + } + } } - Column(modifier = Modifier.padding(horizontal = 16.dp)) { + Column( + modifier = Modifier.padding(horizontal = 16.dp).fillMaxWidth() + .background(color = Color.White) + .align(Alignment.BottomCenter) + ) { Button( isEnabled = true, - btnText = "다음", + btnText = "추천받은 향료를 시향해보세요", onClick = { onNextClick() }, buttonModifier = Modifier.fillMaxWidth(1f).height(52.dp).background(color = Color.Black), textSize = 18, @@ -57,5 +133,5 @@ private fun HbtiProcessScreen(onBackClick: () -> Unit, onNextClick: () -> Unit) @Preview @Composable private fun HbtiProcessScreenPreview() { - HbtiProcessScreen(onBackClick = {}, onNextClick = {}) -} \ No newline at end of file + HbtiProcessScreen(navLogin = {}, onBackClick = {}, onNextClick = {}) +} diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiScreen.kt index 84b4b2a49..968f8f298 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiScreen.kt @@ -206,7 +206,6 @@ private fun HbtiHomeContent( LazyColumn( modifier = Modifier .fillMaxSize() - .padding(horizontal = 16.dp) ) { item { Column { @@ -218,169 +217,173 @@ private fun HbtiHomeContent( onNavClick = onBackClick, navIconColor = Color.White ) - Text( - "당신의 향BTI는 무엇일까요?", - style = TextStyle( - color = Color.White, - fontWeight = FontWeight.Bold, - fontFamily = pretendard, - fontSize = 20.sp - ), - modifier = Modifier.padding(top = 20.dp, bottom = 12.dp) - ) - Text( - "검사를 통해 좋아하는 향료와\n향수까지 알아보세요!", - style = TextStyle( - color = Color.White, - fontWeight = FontWeight.Normal, - fontFamily = pretendard, - fontSize = 14.sp + Column(Modifier.padding(horizontal = 16.dp)) { + Text( + "당신의 향BTI는 무엇일까요?", + style = TextStyle( + color = Color.White, + fontWeight = FontWeight.Bold, + fontFamily = pretendard, + fontSize = 20.sp + ), + modifier = Modifier.padding(top = 20.dp, bottom = 12.dp) ) - ) - Row(modifier = Modifier.padding(top = 20.dp, bottom = 32.dp)) { - Box( - Modifier - .padding(end = 15.dp) - .fillMaxWidth(0.5f) - .height(107.dp) - .clickable { onHbtiSurveyClick() } - .background( - color = Color.Transparent, - shape = RoundedCornerShape(5.dp) - )) { - ImageView( - imageUrl = metadata?.firstImageUrl, - width = 1f, - height = 1f, - backgroundColor = Color.Transparent, - contentScale = ContentScale.FillBounds + Text( + "검사를 통해 좋아하는 향료와\n향수까지 알아보세요!", + style = TextStyle( + color = Color.White, + fontWeight = FontWeight.Normal, + fontFamily = pretendard, + fontSize = 14.sp ) - Column( + ) + Row(modifier = Modifier.padding(top = 20.dp, bottom = 32.dp)) { + Box( + Modifier + .padding(end = 15.dp) + .fillMaxWidth(0.5f) + .height(107.dp) + .clickable { onHbtiSurveyClick() } + .background( + color = Color.Transparent, + shape = RoundedCornerShape(5.dp) + )) { + ImageView( + imageUrl = metadata?.firstImageUrl, + width = 1f, + height = 1f, + backgroundColor = Color.Transparent, + contentScale = ContentScale.FillBounds + ) + Column( + modifier = Modifier + .fillMaxWidth(1f) + .height(107.dp) + ) { + Text( + "향BTI\n검사하러 가기", + style = TextStyle( + color = Color.Black, + fontWeight = FontWeight.Bold, + fontFamily = pretendard, + fontSize = 16.sp + ), + modifier = Modifier.padding(20.dp) + ) + } + } + Box( modifier = Modifier .fillMaxWidth(1f) .height(107.dp) + .background( + color = Color.Transparent, + shape = RoundedCornerShape(5.dp) + ) + .clickable { onAfterOrderClick() } + .background( + color = Color.Transparent, + shape = RoundedCornerShape(5.dp) + ) ) { - Text( - "향BTI\n검사하러 가기", - style = TextStyle( - color = Color.Black, - fontWeight = FontWeight.Bold, - fontFamily = pretendard, - fontSize = 16.sp - ), - modifier = Modifier.padding(20.dp) + ImageView( + imageUrl = metadata?.secondImageUrl, + width = 1f, + height = 1f, + backgroundColor = Color.Transparent, + contentScale = ContentScale.FillBounds ) + Column( + modifier = Modifier + .fillMaxWidth(1f) + .height(107.dp) + ) { + Text( + "향료 입력하기\n(주문 후)", + style = TextStyle( + color = Color.Black, + fontWeight = FontWeight.Bold, + fontFamily = pretendard, + fontSize = 16.sp + ), + modifier = Modifier.padding(20.dp) + ) + } } } - Box( + Row( + verticalAlignment = Alignment.CenterVertically, modifier = Modifier - .fillMaxWidth(1f) - .height(107.dp) - .background( - color = Color.Transparent, - shape = RoundedCornerShape(5.dp) - ) - .clickable { onAfterOrderClick() } + .height(30.dp) .background( color = Color.Transparent, shape = RoundedCornerShape(5.dp) ) ) { ImageView( - imageUrl = metadata?.secondImageUrl, - width = 1f, + imageUrl = "https://github.com/HMOAA/HMOA_ANDROID/assets/67788699/eb5499d5-25e4-4141-af66-353daa76f2a2", + width = 0.1f, height = 1f, backgroundColor = Color.Transparent, - contentScale = ContentScale.FillBounds + contentScale = ContentScale.FillHeight ) - Column( - modifier = Modifier - .fillMaxWidth(1f) - .height(107.dp) + Spacer(Modifier.width(9.dp)) + Text( + "향BTI 후기", + style = TextStyle( + color = Color.White, + fontWeight = FontWeight.Bold, + fontFamily = pretendard, + fontSize = 20.sp + ) + ) + } + Row( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 12.dp), + horizontalArrangement = Arrangement.End + ) { + TextButton( + onClick = onReviewItemClick ) { Text( - "향료 입력하기\n(주문 후)", + "전체보기", style = TextStyle( - color = Color.Black, + color = Color.White, fontWeight = FontWeight.Bold, fontFamily = pretendard, - fontSize = 16.sp + fontSize = 12.sp ), - modifier = Modifier.padding(20.dp) ) } } } - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .height(30.dp) - .background( - color = Color.Transparent, - shape = RoundedCornerShape(5.dp) - ) - ) { - ImageView( - imageUrl = "https://github.com/HMOAA/HMOA_ANDROID/assets/67788699/eb5499d5-25e4-4141-af66-353daa76f2a2", - width = 0.1f, - height = 1f, - backgroundColor = Color.Transparent, - contentScale = ContentScale.FillHeight - ) - Spacer(Modifier.width(9.dp)) - Text( - "향BTI 후기", - style = TextStyle( - color = Color.White, - fontWeight = FontWeight.Bold, - fontFamily = pretendard, - fontSize = 20.sp - ) - ) - } - Row( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 12.dp), - horizontalArrangement = Arrangement.End - ) { - TextButton( - onClick = onReviewItemClick - ) { - Text( - "전체보기", - style = TextStyle( - color = Color.White, - fontWeight = FontWeight.Bold, - fontFamily = pretendard, - fontSize = 12.sp - ), - ) - } - } } } items(reviews) { review -> val images = remember(review.hbtiPhotos) { review.hbtiPhotos.map { it.photoUrl } } - ReviewItem( - isItemClickable = true, - reviewId = review.hbtiReviewId, - profileImg = review.profileImgUrl, - nickname = review.author, - writtenAt = review.createdAt, - isLiked = review.isLiked, - heartNumber = review.heartCount, - content = review.content, - images = images, - category = review.orderTitle, - onHeartClick = onHeartClick, - onMenuClick = { - selectedReview = review - dialogOpen() - }, - onItemClick = onReviewItemClick - ) - Spacer(Modifier.height(12.dp)) + Column(Modifier.padding(horizontal = 16.dp)) { + ReviewItem( + isItemClickable = true, + reviewId = review.hbtiReviewId, + profileImg = review.profileImgUrl, + nickname = review.author, + writtenAt = review.createdAt, + isLiked = review.isLiked, + heartNumber = review.heartCount, + content = review.content, + images = images, + category = review.orderTitle, + onHeartClick = onHeartClick, + onMenuClick = { + selectedReview = review + dialogOpen() + }, + onItemClick = onReviewItemClick + ) + Spacer(Modifier.height(12.dp)) + } } } } diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/PerfumeRecommendationResultScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/PerfumeRecommendationResultScreen.kt index f7eb32702..711737145 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/PerfumeRecommendationResultScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/PerfumeRecommendationResultScreen.kt @@ -1,6 +1,7 @@ package com.hmoa.feature_hbti.screen import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* @@ -9,6 +10,7 @@ import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource @@ -19,8 +21,10 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.hmoa.core_designsystem.R import com.hmoa.core_designsystem.component.* import com.hmoa.core_designsystem.theme.CustomColor +import com.hmoa.core_designsystem.theme.CustomFont import com.hmoa.core_model.response.PerfumeRecommendResponseDto import com.hmoa.feature_hbti.viewmodel.PerfumeRecommendationResultViewModel import com.hmoa.feature_hbti.viewmodel.PerfumeResultUiState @@ -30,7 +34,7 @@ fun PerfumeRecommendationResultRoute( navBack: () -> Unit, navPerfume: (Int) -> Unit, navHome: () -> Unit, - navLogin:()->Unit, + navLogin: () -> Unit, viewModel: PerfumeRecommendationResultViewModel = hiltViewModel() ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() @@ -44,6 +48,7 @@ fun PerfumeRecommendationResultRoute( perfumes = (uiState as PerfumeResultUiState.Success).perfumes ?: emptyList(), isPriceSortedSelected = (uiState as PerfumeResultUiState.Success).isPriceSortedSelected, isNoteSortedSelected = (uiState as PerfumeResultUiState.Success).isNoteSortedSelected, + isEmptyPriceContentNeedState = (uiState as PerfumeResultUiState.Success).isEmptyPriceContentNeedState, navBack = navBack, navPerfume = navPerfume, onClickButton = navHome, @@ -64,10 +69,11 @@ fun PerfumeRecommendationResultRoute( } @Composable -private fun PerfumeCommentResultContent( +fun PerfumeCommentResultContent( perfumes: List, isPriceSortedSelected: Boolean, isNoteSortedSelected: Boolean, + isEmptyPriceContentNeedState: Boolean, onClickButton: () -> Unit, onClickPriceSorted: () -> Unit, onClickNoteSorted: () -> Unit, @@ -116,10 +122,10 @@ private fun PerfumeCommentResultContent( modifier = Modifier.clickable { onClickNoteSorted() }.padding(start = 7.dp) ) } - /** 임시 더미 데이터 */ PerfumeResult( perfumes = perfumes, - navPerfume = navPerfume + navPerfume = navPerfume, + isEmptyPriceContentNeedState = isEmptyPriceContentNeedState ) Spacer(Modifier.height(30.dp)) } @@ -139,10 +145,34 @@ private fun PerfumeCommentResultContent( } } +@Composable +fun EmptyPricePerfumeRecommendationScreen() { + Column(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 = "설정하신 가격대 내에\n해당하는 향수가 없습니다.", + fontSize = 20.sp, + fontFamily = CustomFont.bold, + ) + Spacer(Modifier.height(17.dp)) + Text( + text = "가격대를 재설정 해주세요.", + fontSize = 16.sp, + fontFamily = CustomFont.regular, + ) + } +} + @OptIn(ExperimentalFoundationApi::class) @Composable private fun PerfumeResult( perfumes: List, + isEmptyPriceContentNeedState: Boolean, navPerfume: (Int) -> Unit, ) { val pagerState = rememberPagerState(pageCount = { perfumes.size }) @@ -151,24 +181,28 @@ private fun PerfumeResult( horizontalAlignment = androidx.compose.ui.Alignment.CenterHorizontally ) { Spacer(Modifier.height(20.dp)) - HorizontalPager( - modifier = Modifier - .padding(horizontal = 25.dp).fillMaxWidth(), - state = pagerState, - contentPadding = PaddingValues(end = 80.dp) - ) { page -> - val perfume = perfumes[page] - Column(modifier = Modifier.padding(end = 15.dp)) { - LikeRowItem( - brand = perfume.brandname ?: "", - itemPicture = perfume.perfumeImageUrl ?: "", - price = perfume.price.toString(), - itemNameKo = perfume.perfumeName ?: "", - itemNameEng = perfume.perfumeEnglishName ?: "", - onClickClose = { /** 아무 이벤트도 실행하지 않음 */ }, - navPerfume = { navPerfume(perfume.perfumeId ?: 0) }, - isCloseButtonExist = false - ) + if (isEmptyPriceContentNeedState) { + EmptyPricePerfumeRecommendationScreen() + } else { + HorizontalPager( + modifier = Modifier + .padding(horizontal = 25.dp).fillMaxWidth(), + state = pagerState, + contentPadding = PaddingValues(end = 80.dp) + ) { page -> + val perfume = perfumes[page] + Column(modifier = Modifier.padding(end = 15.dp)) { + LikeRowItem( + brand = perfume.brandname ?: "", + itemPicture = perfume.perfumeImageUrl ?: "", + price = perfume.price.toString(), + itemNameKo = perfume.perfumeName ?: "", + itemNameEng = perfume.perfumeEnglishName ?: "", + onClickClose = { /** 아무 이벤트도 실행하지 않음 */ }, + navPerfume = { navPerfume(perfume.perfumeId ?: 0) }, + isCloseButtonExist = false + ) + } } } } @@ -195,6 +229,7 @@ fun PerfumeRecommendationsResultPreview() { navPerfume = {}, onClickButton = {}, onClickPriceSorted = {}, - onClickNoteSorted = {} + onClickNoteSorted = {}, + isEmptyPriceContentNeedState = false ) -} \ No newline at end of file +} diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiProcessViewmodel.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiProcessViewmodel.kt new file mode 100644 index 000000000..cb39c21c8 --- /dev/null +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiProcessViewmodel.kt @@ -0,0 +1,104 @@ +package com.hmoa.feature_hbti.viewmodel + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.hmoa.core_common.* +import com.hmoa.core_domain.repository.HshopRepository +import com.hmoa.core_model.response.OrderDescriptionResponseDto +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.* +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class HbtiProcessViewmodel @Inject constructor(private val hbtiRepository: HshopRepository) : ViewModel() { + private var _titlesState = MutableStateFlow>(emptyList()) + private var _contentsState = MutableStateFlow>(emptyList()) + private var _imgUrlState = MutableStateFlow("") + private var expiredTokenErrorState = MutableStateFlow(false) + private var wrongTypeTokenErrorState = MutableStateFlow(false) + private var unLoginedErrorState = MutableStateFlow(false) + private var generalErrorState = MutableStateFlow>(Pair(false, null)) + val errorUiState: StateFlow = combine( + expiredTokenErrorState, + wrongTypeTokenErrorState, + unLoginedErrorState, + generalErrorState + ) { expiredTokenError, wrongTypeTokenError, unknownError, generalError -> + ErrorUiState.ErrorData( + expiredTokenError = expiredTokenError, + wrongTypeTokenError = wrongTypeTokenError, + unknownError = unknownError, + generalError = generalError + ) + }.stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5_000), + initialValue = ErrorUiState.Loading + ) + val uiState: StateFlow = + combine(_titlesState, _contentsState, _imgUrlState) { titles, contents, imgUrl -> + HbtiProcessUiState.Success( + titles = titles, + contents = contents, + descriptionUrl = imgUrl + ) + }.stateIn( + scope = viewModelScope, + started = SharingStarted.WhileSubscribed(5_000), + initialValue = HbtiProcessUiState.Loading + ) + + init { + getOrderProcessDescription() + } + + fun getOrderProcessDescription() { + viewModelScope.launch { + flow { + val response = hbtiRepository.getOrderDescriptions() + response.emitOrThrow { emit(it) } + }.asResult().collectLatest { result -> + when (result) { + is Result.Success -> { + updateTitlesAndContents(result.data.data) + _imgUrlState.update { result.data.data?.orderDescriptionImgUrl ?: "" } + } + + is Result.Error -> { + handleErrorType( + error = result.exception, + onExpiredTokenError = { expiredTokenErrorState.update { true } }, + onUnknownError = { unLoginedErrorState.update { true } }, + onWrongTypeTokenError = { wrongTypeTokenErrorState.update { true } }, + onGeneralError = { generalErrorState.update { Pair(true, result.exception.message) } } + ) + } + + Result.Loading -> {} + } + } + } + } + + fun updateTitlesAndContents(result: OrderDescriptionResponseDto?) { + val titles = mutableListOf() + val contents = mutableListOf() + result?.orderDescriptions?.map { + titles.add(it.title) + contents.add(it.content) + } + _titlesState.update { titles } + _contentsState.update { contents } + } +} + +sealed interface HbtiProcessUiState { + data object Error : HbtiProcessUiState + data object Loading : HbtiProcessUiState + data class Success( + val titles: List, + val contents: List, + val descriptionUrl: String, + ) : HbtiProcessUiState +} diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/PerfumeRecommendationResultViewModel.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/PerfumeRecommendationResultViewModel.kt index 6718226e4..b4fed3368 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/PerfumeRecommendationResultViewModel.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/PerfumeRecommendationResultViewModel.kt @@ -14,8 +14,11 @@ class PerfumeRecommendationResultViewModel @Inject constructor( private val surveyRepository: SurveyRepository, ) : ViewModel() { private var _perfumesState = MutableStateFlow>(listOf()) + val perfumesState: StateFlow> = _perfumesState private var _isPriceSortedSelectedState = MutableStateFlow(true) private var _isNoteSortedSelectedState = MutableStateFlow(false) + private var _isEmptyPriceContentNeedState = MutableStateFlow(true) + val isEmptyPriceContentNeedState: StateFlow = _isEmptyPriceContentNeedState private var expiredTokenErrorState = MutableStateFlow(false) private var wrongTypeTokenErrorState = MutableStateFlow(false) private var unLoginedErrorState = MutableStateFlow(false) @@ -42,10 +45,11 @@ class PerfumeRecommendationResultViewModel @Inject constructor( combine( _perfumesState, _isPriceSortedSelectedState, - _isNoteSortedSelectedState - ) { perfumes, isPriceSortedSelected, isNoteSortedSelected -> + _isNoteSortedSelectedState, + _isEmptyPriceContentNeedState + ) { perfumes, isPriceSortedSelected, isNoteSortedSelected, isEmptyPriceContentNeedState -> PerfumeResultUiState.Success( - perfumes, isPriceSortedSelected, isNoteSortedSelected + perfumes, isPriceSortedSelected, isNoteSortedSelected, isEmptyPriceContentNeedState ) }.stateIn( scope = viewModelScope, @@ -60,6 +64,7 @@ class PerfumeRecommendationResultViewModel @Inject constructor( fun insertPriceSortedPerfumes() { _isPriceSortedSelectedState.update { true } _isNoteSortedSelectedState.update { false } + validatePricePerfumeRecommendation(surveyRepository.getPriceSortedPerfumeRecommendsResult().data?.recommendPerfumes) _perfumesState.update { surveyRepository.getPriceSortedPerfumeRecommendsResult().data?.recommendPerfumes ?: listOf() } @@ -68,10 +73,19 @@ class PerfumeRecommendationResultViewModel @Inject constructor( fun insertNoteSortedPerfumes() { _isPriceSortedSelectedState.update { false } _isNoteSortedSelectedState.update { true } + _isEmptyPriceContentNeedState.update { false } _perfumesState.update { surveyRepository.getNoteSortedPerfumeRecommendsResult().data?.recommendPerfumes ?: listOf() } } + + fun validatePricePerfumeRecommendation(recommendation: List?) { + if (recommendation.isNullOrEmpty()) { + _isEmptyPriceContentNeedState.update { true } + } else { + _isEmptyPriceContentNeedState.update { false } + } + } } sealed interface PerfumeResultUiState { @@ -79,8 +93,9 @@ sealed interface PerfumeResultUiState { data class Success( val perfumes: List?, val isPriceSortedSelected: Boolean, - val isNoteSortedSelected: Boolean + val isNoteSortedSelected: Boolean, + val isEmptyPriceContentNeedState: Boolean ) : PerfumeResultUiState data object Error : PerfumeResultUiState -} \ No newline at end of file +} diff --git a/feature-hbti/src/test/java/com/hmoa/feature_hbti/HbtiSurveyViewModelTest.kt b/feature-hbti/src/test/java/com/hmoa/feature_hbti/HbtiSurveyViewModelTest.kt index 908e02067..0c8be0f45 100644 --- a/feature-hbti/src/test/java/com/hmoa/feature_hbti/HbtiSurveyViewModelTest.kt +++ b/feature-hbti/src/test/java/com/hmoa/feature_hbti/HbtiSurveyViewModelTest.kt @@ -2,10 +2,10 @@ package com.hmoa.feature_hbti import ResultResponse import com.hmoa.core_common.ErrorMessageType -import com.hmoa.core_domain.repository.SurveyRepository -import com.hmoa.core_model.data.ErrorMessage import com.hmoa.core_domain.entity.data.HbtiQuestionItem import com.hmoa.core_domain.entity.data.HbtiQuestionItems +import com.hmoa.core_domain.repository.SurveyRepository +import com.hmoa.core_model.data.ErrorMessage import com.hmoa.core_model.response.SurveyOptionResponseDto import com.hmoa.core_model.response.SurveyQuestionResponseDto import com.hmoa.core_model.response.SurveyQuestionsResponseDto @@ -89,7 +89,8 @@ class HbtiSurveyViewModelTest : TestCase() { hbtiQuestions = mutableMapOf( 0 to hbtiQuestionItem_singleChoice, 1 to hbtiQuestionItem_multiChoice - ) + ), + questionCounts = 2 ) launch { viewModel.getSurveyQuestions() }.join() assertEquals(expectedValue, viewModel.hbtiQuestionItemsState.value) @@ -244,7 +245,10 @@ class HbtiSurveyViewModelTest : TestCase() { ) ) val expectedValue = - HbtiQuestionItems(hbtiQuestions = mutableMapOf(0 to hbtiQuestionItem_singleChoice, 1 to updatedItem)) + HbtiQuestionItems( + hbtiQuestions = mutableMapOf(0 to hbtiQuestionItem_singleChoice, 1 to updatedItem), + questionCounts = 2 + ) viewModel.getSurveyQuestions() val result = viewModel.getUpdatedHbtiQuestionItems(page = 1, newHbtiQuestionItem = updatedItem) @@ -267,7 +271,8 @@ class HbtiSurveyViewModelTest : TestCase() { hbtiQuestionItem_multiChoice.optionIds[1] ) ) - ) + ), + questionCounts = 2 ) viewModel.getSurveyQuestions() viewModel.modifyAnswersToOptionId( @@ -341,4 +346,4 @@ class HbtiSurveyViewModelTest : TestCase() { ) assertEquals(expectedValue, viewModel.isNextQuestionAvailable.value) } -} \ No newline at end of file +} diff --git a/feature-hbti/src/test/java/com/hmoa/feature_hbti/NotePickViewmodelTest.kt b/feature-hbti/src/test/java/com/hmoa/feature_hbti/NotePickViewmodelTest.kt index e211296cb..bdebaca0a 100644 --- a/feature-hbti/src/test/java/com/hmoa/feature_hbti/NotePickViewmodelTest.kt +++ b/feature-hbti/src/test/java/com/hmoa/feature_hbti/NotePickViewmodelTest.kt @@ -143,7 +143,11 @@ class NotePickViewmodelTest : TestCase() { ) } launch { viewmodel.getNoteProducts() }.join() - launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value) }.join() + launch { + viewmodel.initializeIsNoteSelectedList( + viewmodel.noteProductState.value, + onUpdateProducts = {}) + }.join() Assert.assertEquals(expectedNoteSelectData, viewmodel.isNoteSelectDataState.value) } @@ -151,7 +155,7 @@ class NotePickViewmodelTest : TestCase() { fun `test_1NoteSelect_reflectsInNoteSelectData`() = coroutineRule.runTest { viewmodel.getTopRecommendedNote() launch { viewmodel.getNoteProducts() }.join() - launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value) }.join() + launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value, {}) }.join() val targetNode = noteProducts.data!!.data[0] viewmodel.handleNoteSelectData( index = 0, @@ -258,7 +262,7 @@ class NotePickViewmodelTest : TestCase() { //Given: 초기화 viewmodel.getTopRecommendedNote() launch { viewmodel.getNoteProducts() }.join() - launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value) }.join() + launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value, {}) }.join() //Then: 버튼의 사용가능여부 = false이다 Assert.assertEquals(false, viewmodel.isNextButtonAvailableState.value) } @@ -268,7 +272,7 @@ class NotePickViewmodelTest : TestCase() { //Given: 초기화 viewmodel.getTopRecommendedNote() launch { viewmodel.getNoteProducts() }.join() - launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value) }.join() + launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value, {}) }.join() val targetNode = noteProducts.data!!.data[0] //When:targetNode만 선택한다 viewmodel.handleNoteSelectData( @@ -290,7 +294,7 @@ class NotePickViewmodelTest : TestCase() { //Given: 초기화 후 targetNode만 선택한다 viewmodel.getTopRecommendedNote() launch { viewmodel.getNoteProducts() }.join() - launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value) }.join() + launch { viewmodel.initializeIsNoteSelectedList(viewmodel.noteProductState.value, {}) }.join() val targetNode = noteProducts.data!!.data[0] viewmodel.handleNoteSelectData( index = 0, diff --git a/feature-hbti/src/test/java/com/hmoa/feature_hbti/PerfumeRecommendationResultViewmodelTest.kt b/feature-hbti/src/test/java/com/hmoa/feature_hbti/PerfumeRecommendationResultViewmodelTest.kt new file mode 100644 index 000000000..864f32326 --- /dev/null +++ b/feature-hbti/src/test/java/com/hmoa/feature_hbti/PerfumeRecommendationResultViewmodelTest.kt @@ -0,0 +1,74 @@ +package com.hmoa.feature_hbti + +import ResultResponse +import com.hmoa.core_domain.repository.SurveyRepository +import com.hmoa.core_model.response.PerfumeRecommendResponseDto +import com.hmoa.core_model.response.PerfumeRecommendsResponseDto +import com.hmoa.feature_hbti.viewmodel.PerfumeRecommendationResultViewModel +import junit.framework.TestCase +import kotlinx.coroutines.runBlocking +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.mockito.Mockito +import org.mockito.Mockito.mock + +class PerfumeRecommendationResultViewmodelTest : TestCase() { + @get:Rule(order = 0) + val coroutineRule = TestCoroutineRule() + + private val surveyRepository = mock(SurveyRepository::class.java) + lateinit var viewmodel: PerfumeRecommendationResultViewModel + lateinit var notePerfumeRecommendationResult: List + lateinit var pricePerfumeRecommendationResult: List + + @Before + override fun setUp() { + super.setUp() + notePerfumeRecommendationResult = listOf( + PerfumeRecommendResponseDto( + brandname = "샤넬", + perfumeId = 0, + perfumeName = "넘버.1", + perfumeEnglishName = "No.1", + perfumeImageUrl = "", + price = 100000 + ) + ) + pricePerfumeRecommendationResult = listOf() + runBlocking { + Mockito.`when`(surveyRepository.getNoteSortedPerfumeRecommendsResult()) + .thenReturn(ResultResponse(PerfumeRecommendsResponseDto(recommendPerfumes = notePerfumeRecommendationResult))) + Mockito.`when`(surveyRepository.getPriceSortedPerfumeRecommendsResult()) + .thenReturn(ResultResponse(PerfumeRecommendsResponseDto(recommendPerfumes = pricePerfumeRecommendationResult))) + viewmodel = PerfumeRecommendationResultViewModel(surveyRepository) + } + } + + @Test + fun `test_getPriceRecommendationPerfume_EmptyPerfumes`() { + viewmodel.insertPriceSortedPerfumes() + assertEquals(viewmodel.perfumesState.value, emptyList()) + } + + @Test + fun `test_insertNoteAfterInsertPrice_reflectsInNotePerfumes`() { + viewmodel.insertPriceSortedPerfumes() + viewmodel.insertNoteSortedPerfumes() + assertEquals(viewmodel.perfumesState.value, notePerfumeRecommendationResult) + } + + @Test + fun `test_insertNoteAfterInsertPrice_reflectsInIsEmptyPriceContentNeedState`() { + viewmodel.insertPriceSortedPerfumes() + viewmodel.insertNoteSortedPerfumes() + assertEquals(viewmodel.isEmptyPriceContentNeedState.value, false) + } + + @Test + fun `test_insertPriceAfterInsertNote_reflectsInIsEmptyPriceContentNeedState`() { + viewmodel.insertNoteSortedPerfumes() + viewmodel.insertPriceSortedPerfumes() + assertEquals(viewmodel.isEmptyPriceContentNeedState.value, true) + } +} From b724f3b14982f6090248d6e8c347e9c83542fca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 19 Nov 2024 22:53:32 +0900 Subject: [PATCH 34/93] =?UTF-8?q?Design:=20=EB=94=94=EC=9E=90=EC=9D=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../screen/HbtiSurveyResultScreen.kt | 143 ++++++++++-------- .../feature_hbti/screen/NotePickScreen.kt | 2 +- 2 files changed, 77 insertions(+), 68 deletions(-) diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyResultScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyResultScreen.kt index d6870146c..112bff121 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyResultScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyResultScreen.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.layout.ContentScale 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.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -99,73 +100,81 @@ private fun HbtiSurveyResultContent( navIcon = painterResource(com.hmoa.core_designsystem.R.drawable.ic_back), onNavClick = { onBackClick() } ) - Column(modifier = Modifier.padding(start = 16.dp)) { - Text( - "${userName}님에게 딱 맞는 향료는\n'${surveyResult[0].noteName}'입니다", - style = TextStyle(fontSize = 20.sp, fontWeight = FontWeight.Bold, fontFamily = pretendard), - modifier = Modifier.padding(top = 20.dp, bottom = 12.dp) - ) - Text( - "2위 : ${surveyResult[1].noteName}", - style = TextStyle( - fontSize = 14.sp, - fontWeight = FontWeight.Medium, - fontFamily = pretendard, - color = CustomColor.gray3 - ), - modifier = Modifier.padding(bottom = 5.dp) - ) - Text( - "3위 : ${surveyResult[2].noteName}", - style = TextStyle( - fontSize = 14.sp, - fontWeight = FontWeight.Medium, - fontFamily = pretendard, - color = CustomColor.gray3 + Column(modifier = Modifier.padding(start = 16.dp), verticalArrangement = Arrangement.SpaceBetween) { + Column { + Text( + "${userName}님에게 딱 맞는 향료는\n'${surveyResult[0].noteName}'입니다", + style = TextStyle(fontSize = 20.sp, fontWeight = FontWeight.Bold, fontFamily = pretendard), + modifier = Modifier.padding(top = 20.dp, bottom = 12.dp) ) - ) - HorizontalPager( - verticalAlignment = Alignment.Bottom, - state = pagerState, - modifier = Modifier.fillMaxWidth().padding(top = 29.dp), - contentPadding = PaddingValues(end = 80.dp) - ) { page -> - Column(modifier = Modifier.fillMaxWidth(1f).fillMaxHeight(0.8f).padding(end = 15.dp)) { - Column( - modifier = Modifier.fillMaxWidth(1f).fillMaxHeight(0.7f) - ) { - ImageView( - imageUrl = surveyResult[page].notePhotoUrl, - width = 1f, - height = 1f, - contentScale = ContentScale.Crop, - backgroundColor = Color.White - ) - } - Column( - modifier = Modifier - .background(color = Color.Black).fillMaxHeight(1f) - ) { - Text( - "${surveyResult[page].noteName}", - style = TextStyle( - fontFamily = pretendard, - fontSize = 16.sp, - fontWeight = FontWeight.Bold, - color = Color.White - ), - modifier = Modifier.padding(bottom = 7.dp, top = 20.dp).padding(horizontal = 20.dp) - ) - Text( - "${surveyResult[page].content}", - style = TextStyle( - fontFamily = pretendard, - fontSize = 12.sp, - fontWeight = FontWeight.Light, - color = Color.White - ), - modifier = Modifier.padding(bottom = 20.dp).padding(horizontal = 20.dp) - ) + Text( + "2위 : ${surveyResult[1].noteName}", + style = TextStyle( + fontSize = 14.sp, + fontWeight = FontWeight.Medium, + fontFamily = pretendard, + color = CustomColor.gray3 + ), + modifier = Modifier.padding(bottom = 5.dp) + ) + Text( + "3위 : ${surveyResult[2].noteName}", + style = TextStyle( + fontSize = 14.sp, + fontWeight = FontWeight.Medium, + fontFamily = pretendard, + color = CustomColor.gray3 + ) + ) + } + + Column { + HorizontalPager( + verticalAlignment = Alignment.Bottom, + state = pagerState, + modifier = Modifier.fillMaxWidth().padding(vertical = 16.dp), + contentPadding = PaddingValues(end = 80.dp) + ) { page -> + Column(modifier = Modifier.fillMaxWidth().fillMaxHeight(0.9f).padding(end = 15.dp)) { + Column( + modifier = Modifier.fillMaxWidth().fillMaxHeight(0.7f) + ) { + ImageView( + imageUrl = surveyResult[page].notePhotoUrl, + width = 1f, + height = 1f, + contentScale = ContentScale.Crop, + backgroundColor = Color.White + ) + } + Column( + modifier = Modifier + .background(color = Color.Black).fillMaxHeight() + .padding(bottom = 20.dp) + ) { + Text( + "${surveyResult[page].noteName}", + style = TextStyle( + fontFamily = pretendard, + fontSize = 16.sp, + fontWeight = FontWeight.Bold, + color = Color.White + ), + modifier = Modifier.padding(bottom = 7.dp, top = 20.dp) + .padding(horizontal = 20.dp) + ) + Text( + "${surveyResult[page].content}", + style = TextStyle( + fontFamily = pretendard, + fontSize = 12.sp, + fontWeight = FontWeight.Light, + color = Color.White + ), + modifier = Modifier.padding(horizontal = 20.dp), + overflow = TextOverflow.Visible + ) + } } } } @@ -214,4 +223,4 @@ private fun HbtiSurveyResultPreview() { HbtiSurveyResultContent(surveyResult = result, onHbtiProcessClick = {}, "테스터", onBackClick = {}) -} \ No newline at end of file +} diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt index d948b891b..c2a4c15ca 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt @@ -141,7 +141,7 @@ fun NoteContent( textAlign = TextAlign.Start ) Text( - "향료 1개당 900원", + "개별구매 불가 SET 로만 구성 (향료 1개당 900원)", modifier = Modifier.padding(bottom = 28.dp), style = TextStyle( color = CustomColor.gray5, From 2927c68c6f3151dbbd3407e0a38321ea122042c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 19 Nov 2024 23:01:09 +0900 Subject: [PATCH 35/93] =?UTF-8?q?Chore:=20=EB=B2=84=EC=A0=84=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=88=98=EC=A0=95=2027->28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c38cbc0c2..c3b2da1a9 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,4 +1,4 @@ -import java.util.Properties +import java.util.* plugins { id("com.android.application") @@ -22,7 +22,7 @@ android { applicationId = "com.hmoa.app" minSdk = 26 targetSdk = 34 - versionCode = 27 + versionCode = 28 versionName = "1.1.4" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" From 54d31854a76a130cc09997a4c92d5fcf7a4dcb5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 19 Nov 2024 23:20:38 +0900 Subject: [PATCH 36/93] =?UTF-8?q?Design:=20=EB=B2=84=ED=8A=BC=20=ED=81=AC?= =?UTF-8?q?=EA=B8=B0=20=EC=9E=91=EC=95=84=EC=A7=80=EB=8A=94=20=ED=98=84?= =?UTF-8?q?=EC=83=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/SurveyOptionList.kt | 2 +- .../feature_hbti/screen/HbtiSurveyScreen.kt | 85 +++++++++---------- 2 files changed, 40 insertions(+), 47 deletions(-) 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 b1bea4788..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 @@ -130,4 +130,4 @@ fun SurveyOptionItemPreview() { radious = 5 ) } -} \ No newline at end of file +} diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt index f9fa85495..07c17834a 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt @@ -164,55 +164,48 @@ fun HbtiSurveyContent( onNavClick = onBackClick ) Column( - modifier = Modifier.padding(horizontal = 16.dp).padding(bottom = 40.dp).fillMaxHeight(1f), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.SpaceBetween, + modifier = Modifier.fillMaxWidth().fillMaxHeight(1f).background(color = Color.White) + .padding(top = 12.dp).padding(horizontal = 16.dp) + .semantics { testTag = "HbtiSurveyForm" } ) { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.SpaceBetween, - modifier = Modifier.fillMaxWidth().fillMaxHeight(1f).background(color = Color.White) - .padding(top = 12.dp) - .semantics { testTag = "HbtiSurveyForm" } - ) { - Column { - ProgressBar(percentage = currentProgress) - HorizontalPager( - userScrollEnabled = isNextQuestionAvailable?.get(pagerState.currentPage) ?: true, - modifier = Modifier.fillMaxWidth().background(color = Color.White), - state = pagerState, - verticalAlignment = Alignment.Top, - ) { page -> - Column(verticalArrangement = Arrangement.SpaceBetween) { - Column(modifier = Modifier.fillMaxWidth()) { - Text( - "Q. ${hbtiQuestionItems?.hbtiQuestions?.get(page)?.questionContent}", - modifier = Modifier.padding(bottom = 32.dp, top = 36.dp), - style = TextStyle( - fontSize = 20.sp, - fontWeight = FontWeight.SemiBold, - fontFamily = CustomFont.regular - ) - ) - SurveyOptionList( - isMutipleAnswerAvailable = hbtiQuestionItems?.hbtiQuestions?.get(page)?.isMultipleChoice!!, - answerIds = hbtiAnswerIds?.get(page) ?: emptyList(), - surveyOptions = hbtiQuestionItems?.hbtiQuestions?.get(page)?.optionContents - ?: listOf(), - surveyOptionIds = hbtiQuestionItems?.hbtiQuestions?.get(page)?.optionIds - ?: listOf(), - onButtonClick = { optionIndex, isGoToSelectedState -> - onClickOption( - hbtiQuestionItems?.hbtiQuestions?.get(page)!!.optionIds[optionIndex], - page, - hbtiQuestionItems?.hbtiQuestions?.get(page)!!, - isGoToSelectedState - ) - } - ) - } - + ProgressBar(percentage = currentProgress) + HorizontalPager( + userScrollEnabled = isNextQuestionAvailable?.get(pagerState.currentPage) ?: true, + modifier = Modifier.fillMaxWidth().background(color = Color.White).fillMaxHeight(0.85f), + state = pagerState, + verticalAlignment = Alignment.Top, + ) { page -> + Column(modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.SpaceBetween) { + Text( + "Q. ${hbtiQuestionItems?.hbtiQuestions?.get(page)?.questionContent}", + modifier = Modifier.padding(bottom = 32.dp, top = 36.dp), + style = TextStyle( + fontSize = 20.sp, + fontWeight = FontWeight.SemiBold, + fontFamily = CustomFont.regular + ) + ) + SurveyOptionList( + isMutipleAnswerAvailable = hbtiQuestionItems?.hbtiQuestions?.get(page)?.isMultipleChoice!!, + answerIds = hbtiAnswerIds?.get(page) ?: emptyList(), + surveyOptions = hbtiQuestionItems?.hbtiQuestions?.get(page)?.optionContents + ?: listOf(), + surveyOptionIds = hbtiQuestionItems?.hbtiQuestions?.get(page)?.optionIds + ?: listOf(), + onButtonClick = { optionIndex, isGoToSelectedState -> + onClickOption( + hbtiQuestionItems?.hbtiQuestions?.get(page)!!.optionIds[optionIndex], + page, + hbtiQuestionItems?.hbtiQuestions?.get(page)!!, + isGoToSelectedState + ) } - } + ) } + } + Column(modifier = Modifier.padding(bottom = 40.dp)) { if (pagerState.currentPage < pagerState.pageCount - 1) { Button( isEnabled = isNextQuestionAvailable?.get(pagerState.currentPage) ?: true, From 717858051f8aa30c05904b2446e50da3d28359c7 Mon Sep 17 00:00:00 2001 From: Lee YongIn <67788699+LeeYongIn0517@users.noreply.github.com> Date: Wed, 20 Nov 2024 01:13:40 +0900 Subject: [PATCH 37/93] =?UTF-8?q?Feature/hbti=20=EB=94=94=EC=9E=90?= =?UTF-8?q?=EC=9D=B8=20=EC=88=98=EC=A0=95=20(#185)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Design: 공백 수정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Release 1.0.0(18) 출시 (#147) * Feature-Magazine Init * Chore: Manifest 정리 * Chore: 기본 의존성 설정 * Chore: Test 관련 의존성 정리 * Chore: Compose 설정 * Feat: Response Dto 추가 * Feat: Magazine Screen 추가 * Feat: Magazine Service 추가 * Feat: Magazine Service DI 추가 * Resource: Floating Action Button Open Icon 추가 * Feat: Magazine DataStore 추가 * Fix: Response 타입 수정 * Feat: Data Store DI * Feat: Repository DI * Feat: Magazine Repository 추가 * Feat: 최신 향수 받아오는 API 추가 * Feat: 최신 향수 받아오는 DTO 추가 * Resource: 공유 아이콘 추가 * Feat: Magazine ViewModel 로직 추가 * Design: TopBar 투명도 파라미터 추가 * Rename: 파일 명 변경 * Design: 투명도 추가 * Design: Magazine Tag 추가 * Resource: 아이콘 resource 추가 * Fix: Response 타입 변경 * Chore: Magazine 의존성 추가 * Feat: Magazine Navigation 추가 * Fix: Bottom Navigation 내용 변경 * Feat: Magazine 상세 화면 추가 * Feat: Magazine Paging 추가 * Feat: Magazine Route 클래스 추가 * Feat: Magazine 상세 비즈니스 로직 추가 * Fix: Conflict 수정 * Fix: Paging 오류 수정 * Design: title 색상 파라미터 추가 * Design: title 색상 파라미터 추가 * Design: review content 위치 변경 * Design: Content 글자 수 제한 * Design: title 글자 수 제한 * Fix: 개행문자 수정 * Feat: Navigation 이벤트 추가 * Feat: Magazine 상세 화면 추가 * Feat: Magazine 상세 화면 비즈니스 로직 추가 * Feat: Navigation 이벤트 추가 * Fix: 데이터 순서에 따른 오류 수정 * Design: Tag UI 수정 * Design: Space 크기 조절 * Feat: 좋아요 update 이벤트 추가 * Fix: Navigation 이벤트 파라미터 추가 * Feat: Navigation 이벤트 파라미터 추가 * Design: Magazine UI 위치 수정 * Fix: Magazine Image 추가 * Resource: Magazine Icon 추가 * Design: 바텀 네비게이션 UI 수정 * Feat: Navigation SingleTop 옵션 추가 * Feat: 좋아요 한 향수 페이지 위치 변동 * FIX: 비로그인 에러다이얼로그 동작 오류 수정 * Fix: Navigation 누락 오류 수정 * Fix: err state 누락 오류 수정 * Fix: navigation 누락 수정 * Design: UI 간격 수정 * Gradle: Material 의존성 추가 * Design: 수정 모달 추가 * Refactor: Dialog 팝업 방식 변경 * FIX: 좋아요 리프레싱 시 리컴포지션 안되는 오류 수정 * Rename: 이름 혼동 방지 * Rename: 이름 혼동 방지 * Fix: Dialog Pop up 시 깜빡거림 수정 * Feat: 향수페이지 댓글 오류 수정 * Fix: 향수 페이지 댓글 상태관리 변화 오류 수정 * Delete: 사용하지 않는 상태관리 변수 삭제 * Update README.md * Resource: Font 추가 * Create android.yml develop 브랜치로 코드 푸시, PR 시 빌드되는 기능 * Feat: 자동 빌드 기능 테스트 구문 * Update android.yml * Feat: 자바 버전 11 -> 17 * Fix: CI환경 빌드에 local.properties 파일 동적 생성 기능 추가 * Fix: 경로 오류 수정 * Feat: 모든 모듈의 local-properties파일 삭제 명령파일 생성 * Fix: app 모듈왜 local.properties를 사용하는 모듈도 파일 동적생성 적용 * Chore: 서브 모듈 추가 * Delete: mylibrary 모듈 삭제 * Chore: AndroidSecretSecure 서브 레포지토리 추가 * Revert "Delete: mylibrary 모듈 삭제" This reverts commit cc0c0fd6d21b7f3d941ed11ab515ff2bf6b8e8ab. * Revert "Chore: 서브 모듈 추가" This reverts commit 95cc85845823843a72eb29a6b65a001b99947c6f. * Fix: 소셜 토큰 api 호출 오류 수정 * Ignore * Fix: lateinit 삭제 및 초기화 값 지정 * Fix: IndexOutOfBoundException방지 구문 추가 * Chore: google-service.json 파일 추가 * Rename * Chore: NATIVE_APP_KEY 적용 * Chore: 버전 증가 6->7 * Feat: 토큰 유무 검사 로직 수정 * Feat: 토큰 가져오는 비동기 작업 -> 동기로 변경 * Fix: 토큰 갱신 작업 대기방식을 동기적으로 변경 * Fix: 스트림 닫힘 오류 원인 부분 해결 * Revert "Feat: 토큰 가져오는 비동기 작업 -> 동기로 변경" This reverts commit f56f46f1000603260a6f143dd4304ffc1b4750bf. * Fix: postFcmToken NullPointException 원인구문 삭제 * Fix: 인터셉터 토큰 추가동작 수정 비동기 -> 동기 * Chore: v1.0.0 버전코드 수정 (7->8) * Fix: native app key, string value로 변경 * Fix: HttpLoggingInterceptor 제거 - IllgalStateException 해결을 위해 지워봄 * Refactor: HPediaDesc api호출 분리 및 CastException 해결 * Chore: 버전코드 수정(8->9) * Chore: 버전코드 수정 (9->10) * Fix: 변수 명 오류 * Chore: 버전코드 수정(10->11) * Fix: 카카오 앱 키 참조 방식 변경 * Chore: 버전코드 수정(11->12) * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Chore: core-common 의존성 추가 * Delete: 토큰 재발급 임시 로직 삭제 * HotFix: Authenticator 토큰 재발급 및 에러메세지 전달 기능 수정 * Fix: Authenticator 적용 * Fix: api 호출부에 Authenticator 적용 * Delete: 안쓰는 api 삭제 * Refactor: FCM 초기화 및 초기 라우팅 코드 함수로 분리 * Delete: 임시 refreshToken 코드 관련 api 삭제 * Rename: 토큰 관련 클래스 의존성 주입 모듈 이름 수정 * Fix: 토큰 동적 할당 시점 변경 * Fix: 로그인 화면 이동 네비게이션 변경 * Chore: 버전 변경 (v1.1.1 -> v1.1.2) * Chore: ci,cd 구문 변경 및 action.yml 파일 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: ci/cd 워크플로우 임시로 주석처리 및 사용중지 * Chore: android.yml 워크플로우 일시중지 (#164) * Chore: CI 구문 롤백 및 오작동 CI/CD 임시폴더로 분리 * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 * v1.1.1 버전 master로 머지합니다 (#163) * Feat: Fcm 관련 함수 추가 * Chore: FCM 모듈 의존성 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Chore: fcm 모듈 환경 설정 추가 * Feat: App Navigation 이벤트 추가 * Chore: FCM 모듈 환경 설정 * Resource: 아이콘 추가 * Feat: 알림 수신 여부 이벤트 추가 * Feat: 알림 화면 추가 * Feat: 알림 화면 비즈니스 로직 추가 * Feat: FCM 모듈 추가 * Feat: 알림 Response 모델 추가 * Feat: 알림 화면 네비게이션 추가 * Design: 읽음 여부에 따른 배경색 조절 * Test: 테스트 코드 추가 * Feat: App Scheme 추가 * Feat: Deeplink Navigation 추가 * Ignore * Delete: sample-app 모듈 삭제 * Delete: Hhmoa_android_secret 로컬 폴더 삭제 * Design: Button 컴포넌트 disabled color 이름 적용 * Feat: Hbti설문 아이템 컴포넌트 추가 * Feat: ProgressBar 컴포넌트 생성 * Feat: VerticalStepBar 컴포넌트 생성 * Design: 홈화면 상단 로고 아이콘 추가 * Design: 디자인시스템 모듈 내 컴포넌트에 pretendard 폰트 적용 * Feat: profile 속성 추가 * Feat: send top notification 파라미터 수정 * Feat: profile 속성 추가 * Chore: Activity single top 속성 설정 * Fix: Error Ui State 업데이트 안되는 오류 수정 * Feat: deeplink 처리 함수 추가 * Refactor: Community, HPedia 네비게이션 분리 * Refactor: Community, HPedia 네비게이션 분리 * Feat: deeplink 설정 * Fix: 경로 설정 오류 수정 * Fix: deeplink 위치 오류 수정 * Fix: Response Dto 형식 오류 수정 * Design: Profile 반영 * Feat: 선택 이벤트 추가 * Feat: Navigation 설정 * Feat: 읽음 처리 함수 추가 * Fix: read 변경 가능하도록 수정 * Test: import 수정 * ignore: git pull * Design: 색상 변경 * Feat: NoteImageItem 생성 * Feat: 권한 설정 여부 정보를 확인 * Feat: 권한 설정 함수 추가 * Ignore * Ignore * Feat: feature-hbti 모듈 생성 * Feat:선택지 무효화 기능 추가 및 SurveyOptionList로 수정 * Rename: SurveyOptionItem -> SurveyOptionList * Feat: ProgressBarPreview에 +/- 효과 추가 * Chore: gradle 의존성 추가 * Fix: intent 이름 변경 * Feat: 알림 선택 시 읽음 처리 이벤트 추가 * Feat: 포그라운드 알림 처리 * Fix: Navigation Deeplink 오류 수정 * Chore: mockito 라이브러리 추가 * Feat: HbtiScreen 추가 * Chore: compose material 및 preview 라이브러리 추가 * Feat: Hbti화면 완성 * Design: 향BTI 화면 디자인 구성 완료 * Feat: 향BTI 테스트 데이터계층 클래스 생성 * Rename: SurveyAnswerResponseDto -> SurveyOptionResponseDto * Feat: fcm token 저장 함수 추가 * Fix: 파라미터 이름 오류 수정 * Fix: 토큰 저장 알고리즘 수정 * Feat: 향수 추천 화면 추가 * Design: 공백 수정 * Feat: 데이터 계층 hilt 주입코드 추가 * Feat: HbtiSurvey 화면 추가(미완성) * Feat: 가격 선택 화면 추가 * Design: 아이템 간 간격 조절 * Rename: 컴포넌트 이름 변경 * Rename: 컴포넌트 이름 변경 * Feat: 향료 선택 화면 추가 * Refactor: 화면 구성 변경 * Fix: 파라미터 변경 * Resource: icon 추가 * Fix: 파라미터 수정 * Feat: 향료 선택 화면 추가 * Style: 공백 스타일 변경 * Fix: 푸쉬 오류 수정 * Style: 코드 스타일 변경 * Feat: 향수 추천 결과 화면 추가 * Rename: 컴포넌트 이름 변경 * Ignore * Delete * Chore: test 라이브러리 추가 * Feat: HbtiSurveyViewmodel 생성 * Test: HbtiSurveyViewModel 테스트 생성 * Test: 테스트 기대값 수정 * Feat: Dto 추가 * Feat: Api 추가 * Style: 코드 라인 변경 * Feat: 비즈니스 로직 추가 * Remove: 삭제 * Feat: 향료 데이터 클래스 추가 * Comment: 주석 추가 * Fix: 서버에 정보 전달 로직 임의 대체 * Rename: 함수 명 변경 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: UI 상태 기준 분기 * Feat: Navigation 설정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: android.yml 워크플로우 일시중지 (#164) * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Fix: 파라미터 명시적으로 구분 * Fix: RouteScreen 파라미터 변수명 변경 반영 * Chore: 버전코드 수정 22->23 * Ignore * Fix: 백업데이터 설정 해제 * Chore: 버전 업데이트 * Release 1.1.2버전 master로 푸시 (#167) * Feat: Fcm 관련 함수 추가 * Chore: FCM 모듈 의존성 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Chore: fcm 모듈 환경 설정 추가 * Feat: App Navigation 이벤트 추가 * Chore: FCM 모듈 환경 설정 * Resource: 아이콘 추가 * Feat: 알림 수신 여부 이벤트 추가 * Feat: 알림 화면 추가 * Feat: 알림 화면 비즈니스 로직 추가 * Feat: FCM 모듈 추가 * Feat: 알림 Response 모델 추가 * Feat: 알림 화면 네비게이션 추가 * Design: 읽음 여부에 따른 배경색 조절 * Test: 테스트 코드 추가 * Feat: App Scheme 추가 * Feat: Deeplink Navigation 추가 * Ignore * Delete: sample-app 모듈 삭제 * Delete: Hhmoa_android_secret 로컬 폴더 삭제 * Design: Button 컴포넌트 disabled color 이름 적용 * Feat: Hbti설문 아이템 컴포넌트 추가 * Feat: ProgressBar 컴포넌트 생성 * Feat: VerticalStepBar 컴포넌트 생성 * Design: 홈화면 상단 로고 아이콘 추가 * Design: 디자인시스템 모듈 내 컴포넌트에 pretendard 폰트 적용 * Feat: profile 속성 추가 * Feat: send top notification 파라미터 수정 * Feat: profile 속성 추가 * Chore: Activity single top 속성 설정 * Fix: Error Ui State 업데이트 안되는 오류 수정 * Feat: deeplink 처리 함수 추가 * Refactor: Community, HPedia 네비게이션 분리 * Refactor: Community, HPedia 네비게이션 분리 * Feat: deeplink 설정 * Fix: 경로 설정 오류 수정 * Fix: deeplink 위치 오류 수정 * Fix: Response Dto 형식 오류 수정 * Design: Profile 반영 * Feat: 선택 이벤트 추가 * Feat: Navigation 설정 * Feat: 읽음 처리 함수 추가 * Fix: read 변경 가능하도록 수정 * Test: import 수정 * ignore: git pull * Design: 색상 변경 * Feat: NoteImageItem 생성 * Feat: 권한 설정 여부 정보를 확인 * Feat: 권한 설정 함수 추가 * Ignore * Ignore * Feat: feature-hbti 모듈 생성 * Feat:선택지 무효화 기능 추가 및 SurveyOptionList로 수정 * Rename: SurveyOptionItem -> SurveyOptionList * Feat: ProgressBarPreview에 +/- 효과 추가 * Chore: gradle 의존성 추가 * Fix: intent 이름 변경 * Feat: 알림 선택 시 읽음 처리 이벤트 추가 * Feat: 포그라운드 알림 처리 * Fix: Navigation Deeplink 오류 수정 * Chore: mockito 라이브러리 추가 * Feat: HbtiScreen 추가 * Chore: compose material 및 preview 라이브러리 추가 * Feat: Hbti화면 완성 * Design: 향BTI 화면 디자인 구성 완료 * Feat: 향BTI 테스트 데이터계층 클래스 생성 * Rename: SurveyAnswerResponseDto -> SurveyOptionResponseDto * Feat: fcm token 저장 함수 추가 * Fix: 파라미터 이름 오류 수정 * Fix: 토큰 저장 알고리즘 수정 * Feat: 향수 추천 화면 추가 * Design: 공백 수정 * Feat: 데이터 계층 hilt 주입코드 추가 * Feat: HbtiSurvey 화면 추가(미완성) * Feat: 가격 선택 화면 추가 * Design: 아이템 간 간격 조절 * Rename: 컴포넌트 이름 변경 * Rename: 컴포넌트 이름 변경 * Feat: 향료 선택 화면 추가 * Refactor: 화면 구성 변경 * Fix: 파라미터 변경 * Resource: icon 추가 * Fix: 파라미터 수정 * Feat: 향료 선택 화면 추가 * Style: 공백 스타일 변경 * Fix: 푸쉬 오류 수정 * Style: 코드 스타일 변경 * Feat: 향수 추천 결과 화면 추가 * Rename: 컴포넌트 이름 변경 * Ignore * Delete * Chore: test 라이브러리 추가 * Feat: HbtiSurveyViewmodel 생성 * Test: HbtiSurveyViewModel 테스트 생성 * Test: 테스트 기대값 수정 * Feat: Dto 추가 * Feat: Api 추가 * Style: 코드 라인 변경 * Feat: 비즈니스 로직 추가 * Remove: 삭제 * Feat: 향료 데이터 클래스 추가 * Comment: 주석 추가 * Fix: 서버에 정보 전달 로직 임의 대체 * Rename: 함수 명 변경 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: UI 상태 기준 분기 * Feat: Navigation 설정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: android.yml 워크플로우 일시중지 (#164) * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Revert "Chore: 버전 업데이트" This reverts commit 031fc2f141d3ffbc07b0954eda874c58d7e1c834. * Revert "Fix: 백업데이터 설정 해제" This reverts commit bb68a8d265be89d74bcc2feed66baca5355cd475. * HotFix: 카카오 sdk 버전 업그레이드 * HotFix: 카카오 sdk 버전 업그레이드 (#170) * HotFix: 카카오 sdk 버전 업그레이드 * Feat: gradlew clean 작업 추가 * Delete * Delete: refreshToken 추상메서드 삭제 * Delete: 토큰 리프레싱 임시방안 코드 삭제 * HotFix: 카카오 sdk 버전 업그레이드 (#174) * Hotfix/community (#176) * Fix: 좋아요 반영 안되는 오류 수정 * Fix: response에 wrapping 추가 * Design: 내용 및 사진 누락 추가 * Fix: response wrapping * Design: 디자인 누락 추가 * Refactor: 불필요 로직 삭제 * Feat: 파라미터 명 변경 * Design: 버튼 가려지는 현상 수정 * Fix: hbti 향료개수 자유선택 후 튕기는 현상 수정 * Fix: hbti 향료 선택결과 제출로직 변경 * Fix: hbti 향료선택화면 하단버튼 disabled 상태관리 추가 * Fix: hbti 향료 카테고리 선택화면 로직 변경 반영 * Test: hbti 향료 카테고리 선택화면 로직 변경사항 테스트 * Design: 백버튼 추가 * Feat: 향료 제품 가격 추가 * Refactor: 플래그 제거 및 콜백으로 대체 * Design: 디자인 마진 변경 * Design: Topbar 배경 수정 * Feat: hbti 홈화면 메타데이터 추가 및 기존 데이터 리팩토링 * Design: 홈 디자인 변경 반영 * Design: Topbar 디폴트 배경 변경 * Feat: 로그인 유무 확인 코드 추가 * Design: 스크롤 초기 위치 수정 * Chore: 버전 코드 변경 (24 -> 25) * Design: 향모아 사업자 정보 추가 * Fix: hbti 메타데이터 요청 오류 임시 주석처리 * Chore: 데이터백업설정 변경 * Chore: 테스트 버전 업그레이드 25->27 * chore: gitignore 파일 추가 * chore: 주석해제 * Feat: 상품 구매 여부 확인 다이얼로그 추가 * Feat: Hbti 설문 양옆 스크롤 기능 추가 * Delete: 주석 삭제 * Fix: LazyColumn으로 변경 후 스크롤위치 초기화 적용 * Refactor: isNoteSelectedData상태 업데이트 함수 수정 * fix: Hbti ProgressBar 리컴포지션 최적화 및 UI 버그 개선 * Design: Hbti 향료 선택화면 디테일 변경 * Fix: nullable 처리 누락 수정 * Feat: 향료주문 과정 설명 화면 api 적용 * Feat: 향료주문 과정 설명 화면 네비게이션 추가 * Feat: 가격대 향수추천 결과 화면 추가 * Test: 향수 추천결과 화면 UI/단위 테스트 작성 * Test: 뷰모델 변경사항 반영한 테스트 수정 * Fix: 브랜드 이미지 삭제 반영 * Design: 상단 바 패딩 불일치 수정 * Fix: 향수 화면의 브랜드 사진 삭제 반영 * Design: 디자인 추가 수정 * Chore: 버전 코드 수정 27->28 * Design: 버튼 크기 작아지는 현상 수정 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> --- app/build.gradle.kts | 4 +- .../component/SurveyOptionList.kt | 2 +- .../hmoa/core_domain/entity/data/Perfume.kt | 1 - .../core_domain/usecase/GetPerfumeUsecase.kt | 5 +- .../response/PerfumeDetailResponseDto.kt | 1 - .../screen/HbtiSurveyResultScreen.kt | 143 ++++++++++-------- .../feature_hbti/screen/HbtiSurveyScreen.kt | 85 +++++------ .../feature_hbti/screen/NotePickScreen.kt | 2 +- .../feature_perfume/screen/PerfumeScreen.kt | 83 +++++----- 9 files changed, 165 insertions(+), 161 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c38cbc0c2..c3b2da1a9 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,4 +1,4 @@ -import java.util.Properties +import java.util.* plugins { id("com.android.application") @@ -22,7 +22,7 @@ android { applicationId = "com.hmoa.app" minSdk = 26 targetSdk = 34 - versionCode = 27 + versionCode = 28 versionName = "1.1.4" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" 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 b1bea4788..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 @@ -130,4 +130,4 @@ fun SurveyOptionItemPreview() { radious = 5 ) } -} \ No newline at end of file +} diff --git a/core-domain/src/main/java/com/hmoa/core_domain/entity/data/Perfume.kt b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/Perfume.kt index bb11a523a..dc0d55d2c 100644 --- a/core-domain/src/main/java/com/hmoa/core_domain/entity/data/Perfume.kt +++ b/core-domain/src/main/java/com/hmoa/core_domain/entity/data/Perfume.kt @@ -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-domain/src/main/java/com/hmoa/core_domain/usecase/GetPerfumeUsecase.kt b/core-domain/src/main/java/com/hmoa/core_domain/usecase/GetPerfumeUsecase.kt index d1c271310..9e86964d4 100644 --- a/core-domain/src/main/java/com/hmoa/core_domain/usecase/GetPerfumeUsecase.kt +++ b/core-domain/src/main/java/com/hmoa/core_domain/usecase/GetPerfumeUsecase.kt @@ -2,9 +2,9 @@ package com.hmoa.core_domain.usecase import ResultResponse import com.hmoa.core_domain.emitOrThrow +import com.hmoa.core_domain.entity.data.Perfume import com.hmoa.core_domain.repository.PerfumeRepository import com.hmoa.core_model.data.ErrorMessage -import com.hmoa.core_domain.entity.data.Perfume import com.hmoa.core_model.response.PerfumeCommentGetResponseDto import com.hmoa.core_model.response.PerfumeCommentResponseDto import com.hmoa.core_model.response.PerfumeDetailResponseDto @@ -25,7 +25,6 @@ class GetPerfumeUsecase @Inject constructor( brandEnglishName = perfumeInfo1.data?.brandEnglishName ?: "", brandKoreanName = perfumeInfo1.data?.brandName ?: "", brandId = perfumeInfo1.data?.brandId.toString(), - brandImgUrl = perfumeInfo1.data?.brandImgUrl ?: "", perfumeEnglishName = perfumeInfo1.data?.englishName ?: "", perfumeKoreanName = perfumeInfo1.data?.koreanName ?: "", baseNote = perfumeInfo1.data?.baseNote ?: "", @@ -162,4 +161,4 @@ enum class TastingNoteImageUrl(val index: Int, val imageUrl: String) { index = 17, imageUrl = "https://github.com/HMOAA/HMOA_ANDROID/assets/67788699/6c5d2111-737f-48bb-b480-5ad883b120c9" ), -} \ No newline at end of file +} diff --git a/core-model/src/main/java/com/hmoa/core_model/response/PerfumeDetailResponseDto.kt b/core-model/src/main/java/com/hmoa/core_model/response/PerfumeDetailResponseDto.kt index 237ffd213..a0889fad1 100644 --- a/core-model/src/main/java/com/hmoa/core_model/response/PerfumeDetailResponseDto.kt +++ b/core-model/src/main/java/com/hmoa/core_model/response/PerfumeDetailResponseDto.kt @@ -7,7 +7,6 @@ data class PerfumeDetailResponseDto( val baseNote: String?, val brandEnglishName: String, val brandId: Int, - val brandImgUrl: String, val brandName: String, val englishName: String, val heartNote: String?, diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyResultScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyResultScreen.kt index d6870146c..112bff121 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyResultScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyResultScreen.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.layout.ContentScale 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.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -99,73 +100,81 @@ private fun HbtiSurveyResultContent( navIcon = painterResource(com.hmoa.core_designsystem.R.drawable.ic_back), onNavClick = { onBackClick() } ) - Column(modifier = Modifier.padding(start = 16.dp)) { - Text( - "${userName}님에게 딱 맞는 향료는\n'${surveyResult[0].noteName}'입니다", - style = TextStyle(fontSize = 20.sp, fontWeight = FontWeight.Bold, fontFamily = pretendard), - modifier = Modifier.padding(top = 20.dp, bottom = 12.dp) - ) - Text( - "2위 : ${surveyResult[1].noteName}", - style = TextStyle( - fontSize = 14.sp, - fontWeight = FontWeight.Medium, - fontFamily = pretendard, - color = CustomColor.gray3 - ), - modifier = Modifier.padding(bottom = 5.dp) - ) - Text( - "3위 : ${surveyResult[2].noteName}", - style = TextStyle( - fontSize = 14.sp, - fontWeight = FontWeight.Medium, - fontFamily = pretendard, - color = CustomColor.gray3 + Column(modifier = Modifier.padding(start = 16.dp), verticalArrangement = Arrangement.SpaceBetween) { + Column { + Text( + "${userName}님에게 딱 맞는 향료는\n'${surveyResult[0].noteName}'입니다", + style = TextStyle(fontSize = 20.sp, fontWeight = FontWeight.Bold, fontFamily = pretendard), + modifier = Modifier.padding(top = 20.dp, bottom = 12.dp) ) - ) - HorizontalPager( - verticalAlignment = Alignment.Bottom, - state = pagerState, - modifier = Modifier.fillMaxWidth().padding(top = 29.dp), - contentPadding = PaddingValues(end = 80.dp) - ) { page -> - Column(modifier = Modifier.fillMaxWidth(1f).fillMaxHeight(0.8f).padding(end = 15.dp)) { - Column( - modifier = Modifier.fillMaxWidth(1f).fillMaxHeight(0.7f) - ) { - ImageView( - imageUrl = surveyResult[page].notePhotoUrl, - width = 1f, - height = 1f, - contentScale = ContentScale.Crop, - backgroundColor = Color.White - ) - } - Column( - modifier = Modifier - .background(color = Color.Black).fillMaxHeight(1f) - ) { - Text( - "${surveyResult[page].noteName}", - style = TextStyle( - fontFamily = pretendard, - fontSize = 16.sp, - fontWeight = FontWeight.Bold, - color = Color.White - ), - modifier = Modifier.padding(bottom = 7.dp, top = 20.dp).padding(horizontal = 20.dp) - ) - Text( - "${surveyResult[page].content}", - style = TextStyle( - fontFamily = pretendard, - fontSize = 12.sp, - fontWeight = FontWeight.Light, - color = Color.White - ), - modifier = Modifier.padding(bottom = 20.dp).padding(horizontal = 20.dp) - ) + Text( + "2위 : ${surveyResult[1].noteName}", + style = TextStyle( + fontSize = 14.sp, + fontWeight = FontWeight.Medium, + fontFamily = pretendard, + color = CustomColor.gray3 + ), + modifier = Modifier.padding(bottom = 5.dp) + ) + Text( + "3위 : ${surveyResult[2].noteName}", + style = TextStyle( + fontSize = 14.sp, + fontWeight = FontWeight.Medium, + fontFamily = pretendard, + color = CustomColor.gray3 + ) + ) + } + + Column { + HorizontalPager( + verticalAlignment = Alignment.Bottom, + state = pagerState, + modifier = Modifier.fillMaxWidth().padding(vertical = 16.dp), + contentPadding = PaddingValues(end = 80.dp) + ) { page -> + Column(modifier = Modifier.fillMaxWidth().fillMaxHeight(0.9f).padding(end = 15.dp)) { + Column( + modifier = Modifier.fillMaxWidth().fillMaxHeight(0.7f) + ) { + ImageView( + imageUrl = surveyResult[page].notePhotoUrl, + width = 1f, + height = 1f, + contentScale = ContentScale.Crop, + backgroundColor = Color.White + ) + } + Column( + modifier = Modifier + .background(color = Color.Black).fillMaxHeight() + .padding(bottom = 20.dp) + ) { + Text( + "${surveyResult[page].noteName}", + style = TextStyle( + fontFamily = pretendard, + fontSize = 16.sp, + fontWeight = FontWeight.Bold, + color = Color.White + ), + modifier = Modifier.padding(bottom = 7.dp, top = 20.dp) + .padding(horizontal = 20.dp) + ) + Text( + "${surveyResult[page].content}", + style = TextStyle( + fontFamily = pretendard, + fontSize = 12.sp, + fontWeight = FontWeight.Light, + color = Color.White + ), + modifier = Modifier.padding(horizontal = 20.dp), + overflow = TextOverflow.Visible + ) + } } } } @@ -214,4 +223,4 @@ private fun HbtiSurveyResultPreview() { HbtiSurveyResultContent(surveyResult = result, onHbtiProcessClick = {}, "테스터", onBackClick = {}) -} \ No newline at end of file +} diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt index f9fa85495..07c17834a 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyScreen.kt @@ -164,55 +164,48 @@ fun HbtiSurveyContent( onNavClick = onBackClick ) Column( - modifier = Modifier.padding(horizontal = 16.dp).padding(bottom = 40.dp).fillMaxHeight(1f), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.SpaceBetween, + modifier = Modifier.fillMaxWidth().fillMaxHeight(1f).background(color = Color.White) + .padding(top = 12.dp).padding(horizontal = 16.dp) + .semantics { testTag = "HbtiSurveyForm" } ) { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.SpaceBetween, - modifier = Modifier.fillMaxWidth().fillMaxHeight(1f).background(color = Color.White) - .padding(top = 12.dp) - .semantics { testTag = "HbtiSurveyForm" } - ) { - Column { - ProgressBar(percentage = currentProgress) - HorizontalPager( - userScrollEnabled = isNextQuestionAvailable?.get(pagerState.currentPage) ?: true, - modifier = Modifier.fillMaxWidth().background(color = Color.White), - state = pagerState, - verticalAlignment = Alignment.Top, - ) { page -> - Column(verticalArrangement = Arrangement.SpaceBetween) { - Column(modifier = Modifier.fillMaxWidth()) { - Text( - "Q. ${hbtiQuestionItems?.hbtiQuestions?.get(page)?.questionContent}", - modifier = Modifier.padding(bottom = 32.dp, top = 36.dp), - style = TextStyle( - fontSize = 20.sp, - fontWeight = FontWeight.SemiBold, - fontFamily = CustomFont.regular - ) - ) - SurveyOptionList( - isMutipleAnswerAvailable = hbtiQuestionItems?.hbtiQuestions?.get(page)?.isMultipleChoice!!, - answerIds = hbtiAnswerIds?.get(page) ?: emptyList(), - surveyOptions = hbtiQuestionItems?.hbtiQuestions?.get(page)?.optionContents - ?: listOf(), - surveyOptionIds = hbtiQuestionItems?.hbtiQuestions?.get(page)?.optionIds - ?: listOf(), - onButtonClick = { optionIndex, isGoToSelectedState -> - onClickOption( - hbtiQuestionItems?.hbtiQuestions?.get(page)!!.optionIds[optionIndex], - page, - hbtiQuestionItems?.hbtiQuestions?.get(page)!!, - isGoToSelectedState - ) - } - ) - } - + ProgressBar(percentage = currentProgress) + HorizontalPager( + userScrollEnabled = isNextQuestionAvailable?.get(pagerState.currentPage) ?: true, + modifier = Modifier.fillMaxWidth().background(color = Color.White).fillMaxHeight(0.85f), + state = pagerState, + verticalAlignment = Alignment.Top, + ) { page -> + Column(modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.SpaceBetween) { + Text( + "Q. ${hbtiQuestionItems?.hbtiQuestions?.get(page)?.questionContent}", + modifier = Modifier.padding(bottom = 32.dp, top = 36.dp), + style = TextStyle( + fontSize = 20.sp, + fontWeight = FontWeight.SemiBold, + fontFamily = CustomFont.regular + ) + ) + SurveyOptionList( + isMutipleAnswerAvailable = hbtiQuestionItems?.hbtiQuestions?.get(page)?.isMultipleChoice!!, + answerIds = hbtiAnswerIds?.get(page) ?: emptyList(), + surveyOptions = hbtiQuestionItems?.hbtiQuestions?.get(page)?.optionContents + ?: listOf(), + surveyOptionIds = hbtiQuestionItems?.hbtiQuestions?.get(page)?.optionIds + ?: listOf(), + onButtonClick = { optionIndex, isGoToSelectedState -> + onClickOption( + hbtiQuestionItems?.hbtiQuestions?.get(page)!!.optionIds[optionIndex], + page, + hbtiQuestionItems?.hbtiQuestions?.get(page)!!, + isGoToSelectedState + ) } - } + ) } + } + Column(modifier = Modifier.padding(bottom = 40.dp)) { if (pagerState.currentPage < pagerState.pageCount - 1) { Button( isEnabled = isNextQuestionAvailable?.get(pagerState.currentPage) ?: true, diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt index d948b891b..c2a4c15ca 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickScreen.kt @@ -141,7 +141,7 @@ fun NoteContent( textAlign = TextAlign.Start ) Text( - "향료 1개당 900원", + "개별구매 불가 SET 로만 구성 (향료 1개당 900원)", modifier = Modifier.padding(bottom = 28.dp), style = TextStyle( color = CustomColor.gray5, diff --git a/feature-perfume/src/main/java/com/hmoa/feature_perfume/screen/PerfumeScreen.kt b/feature-perfume/src/main/java/com/hmoa/feature_perfume/screen/PerfumeScreen.kt index f7ec610bd..0cdb323f7 100644 --- a/feature-perfume/src/main/java/com/hmoa/feature_perfume/screen/PerfumeScreen.kt +++ b/feature-perfume/src/main/java/com/hmoa/feature_perfume/screen/PerfumeScreen.kt @@ -5,8 +5,6 @@ import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ModalBottomSheetLayout import androidx.compose.material.ModalBottomSheetValue @@ -28,17 +26,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.hmoa.core_designsystem.component.AppLoadingScreen -import com.hmoa.core_designsystem.component.Button -import com.hmoa.core_designsystem.component.CommentItem -import com.hmoa.core_designsystem.component.CustomSlider -import com.hmoa.core_designsystem.component.ErrorUiSetView -import com.hmoa.core_designsystem.component.ImageView -import com.hmoa.core_designsystem.component.PerfumeItemView -import com.hmoa.core_designsystem.component.ReportModal -import com.hmoa.core_designsystem.component.TopBar -import com.hmoa.core_designsystem.component.TypeBadge -import com.hmoa.core_designsystem.component.VoteView +import com.hmoa.core_designsystem.component.* import com.hmoa.core_designsystem.theme.CustomColor import com.hmoa.core_designsystem.theme.CustomFont import com.hmoa.core_domain.entity.data.Perfume @@ -249,7 +237,7 @@ fun PerfumeContent( modifier = Modifier.clickable { onBrandClick(data.brandId) }.padding(horizontal = 16.dp) .padding(top = 48.dp) ) { - BrandCard(data.brandImgUrl, data.brandEnglishName, data.brandKoreanName) + BrandCard(data.brandEnglishName, data.brandKoreanName) } TastingNoteView( notes = arrayOf(data.topNote ?: "", data.heartNote ?: "", data.baseNote ?: ""), @@ -287,7 +275,11 @@ fun PerfumeContent( ) Text( "같은 브랜드의 제품", - style = TextStyle(fontSize = 20.sp, fontWeight = FontWeight.Medium, fontFamily = CustomFont.regular), + style = TextStyle( + fontSize = 20.sp, + fontWeight = FontWeight.Medium, + fontFamily = CustomFont.regular + ), modifier = Modifier.padding(end = 4.dp).padding(top = 40.dp) ) Spacer( @@ -382,21 +374,9 @@ fun PerfumeVolumeView(volume: Int, color: Color) { } @Composable -fun BrandCard(imageUrl: String, brandEnglishName: String?, brandKoreanName: String) { +fun BrandCard(brandEnglishName: String?, brandKoreanName: String) { Row(modifier = Modifier.border(border = BorderStroke(width = 1.dp, color = CustomColor.gray3))) { - Column( - modifier = Modifier.width(68.dp).height(68.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center - ) { - ImageView( - imageUrl = imageUrl, - backgroundColor = Color.White, - width = 0.9f, - height = 1f, - contentScale = ContentScale.FillWidth - ) - } + Column( modifier = Modifier.fillMaxWidth().height(68.dp).background(color = Color.Black).padding(start = 10.dp), verticalArrangement = Arrangement.Center @@ -449,7 +429,11 @@ fun TastingNoteView(notes: Array, imageUrls: List, noteTitle: Li ) Text( notes[index], - style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.Medium, fontFamily = CustomFont.regular), + style = TextStyle( + fontSize = 12.sp, + fontWeight = FontWeight.Medium, + fontFamily = CustomFont.regular + ), modifier = Modifier.padding(start = 8.dp) ) } @@ -500,8 +484,10 @@ fun PerfumeWeathernessView(onWeatherClick: (value: Weather) -> Unit, weatherData ) } Text( - "여러분의 생각을 투표해주세요", style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.Medium, fontFamily = CustomFont.regular), - modifier = Modifier.padding(vertical = 20.dp).fillMaxWidth(), textAlign = TextAlign.End + "여러분의 생각을 투표해주세요", + style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.Medium, fontFamily = CustomFont.regular), + modifier = Modifier.padding(vertical = 20.dp).fillMaxWidth(), + textAlign = TextAlign.End ) } @@ -537,8 +523,10 @@ fun PerfumeGenderView(onGenderClick: (value: PerfumeGender) -> Unit, genderData: ) } Text( - "여러분의 생각을 투표해주세요", style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.Medium, fontFamily = CustomFont.regular), - modifier = Modifier.padding(vertical = 20.dp).fillMaxWidth(), textAlign = TextAlign.End + "여러분의 생각을 투표해주세요", + style = TextStyle(fontSize = 12.sp, fontWeight = FontWeight.Medium, fontFamily = CustomFont.regular), + modifier = Modifier.padding(vertical = 20.dp).fillMaxWidth(), + textAlign = TextAlign.End ) } @@ -569,17 +557,24 @@ fun PerfumeAgeView( horizontalArrangement = Arrangement.SpaceBetween ) { Text( - "10대", style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Normal, fontFamily = CustomFont.regular), + "10대", + style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Normal, fontFamily = CustomFont.regular), modifier = Modifier.padding(11.dp) ) if (ageData?.writed == true) { Text( - "평균 ${ageData.age}세", style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Normal, fontFamily = CustomFont.regular), + "평균 ${ageData.age}세", + style = TextStyle( + fontSize = 16.sp, + fontWeight = FontWeight.Normal, + fontFamily = CustomFont.regular + ), modifier = Modifier.padding(11.dp) ) } Text( - "50대 이상", style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Normal, fontFamily = CustomFont.regular) + "50대 이상", + style = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Normal, fontFamily = CustomFont.regular) ) } } @@ -611,7 +606,12 @@ fun CommentView( if (commentCount == 0) { Text( "해당 제품에 대한 의견을 남겨주세요", - style = TextStyle(fontSize = 14.sp, fontWeight = FontWeight.Medium, color = CustomColor.gray3, fontFamily = CustomFont.regular), + style = TextStyle( + fontSize = 14.sp, + fontWeight = FontWeight.Medium, + color = CustomColor.gray3, + fontFamily = CustomFont.regular + ), modifier = Modifier.fillMaxWidth().padding(vertical = 52.dp), textAlign = TextAlign.Center ) @@ -685,7 +685,12 @@ fun BottomToolBar(isLiked: Boolean, onLikeClick: (value: Boolean) -> Unit, onCom Text( "댓글작성", modifier = Modifier.padding(start = 8.dp), - style = TextStyle(fontWeight = FontWeight.Medium, fontSize = 16.sp, color = Color.White, fontFamily = CustomFont.regular) + style = TextStyle( + fontWeight = FontWeight.Medium, + fontSize = 16.sp, + color = Color.White, + fontFamily = CustomFont.regular + ) ) } } From 473a19b92871c8b6414e4c0578430fde17027ed2 Mon Sep 17 00:00:00 2001 From: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> Date: Thu, 21 Nov 2024 22:34:38 +0900 Subject: [PATCH 38/93] =?UTF-8?q?Feature/hbti=20shj=20=EB=A7=88=EC=A7=80?= =?UTF-8?q?=EB=A7=89=20merge=20(#186)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Design: 여백 조정 * Rename: 파라미터 명 변경 * Feat: 환불 api 완료 후에 이전 화면으로 navigation 되도록 설정 * Feat: 가격 계산 관련 비즈니스 로직 수정 * Comment: Log 삭제 * Feat: Web Link 연결에서 Web View 사용으로 변경 * Remove: 미사용 UI 삭제 * Feat: 파라미터 타입 변경 (not null >> nullable) * Feat: 파라미터 값 null 여부에 따른 UI 분기 * Rename: navigation route 클래스 위치 이동 (각 feature 모듈 >> core-domain.entity) * Rename: navigation route 클래스 위치 이동 (각 feature 모듈 >> core-domain.entity) * Rename: navigation 이벤트 명 변경 * Rename: navigation 이벤트 명 변경 * Rename: navigation 이벤트 명 변경 * Rename: entity 위치 변경 (각 feature 모듈 & core-model >> core-domain) * Feat: decode from string import 누락 추가 * Feat: decode from string import 누락 추가 * Feat: 주문 내역 조회 paging 처리 * Feat: nullable 처리 * Rename: 파라미터 명 변경 * Chore: 의존성 중복 제거 * Rename: 파라미터 이름 변경 * Fix: 파라미터 변경 * Rename: navigation 이벤트 명 변경 * Rename: 화면 명 변경 * Feat: 환불/반품 내역 조회 api 추가 * Rename: 함수 이름 변경 (getRefund >> getRefundRecord) * Rename: 함수 이름 변경 (getFavoriteCommentPaging >> getOrderRecordPaging) * Rename: 파일 명 변경 (ReturnOrRefundRecordPage >> RefundRecordPage) * Feat: 반품/환불 내역 비즈니스 로직 추가 * Feat: Empty Data Page 컴포넌트 추가 * Feat: view model 연결 * Feat: view model 추가 * Feat: view model 연결 * Fix: 패키지 명 다른 오류 수정 * Remove: 미사용 resource 삭제 * Rename: 디렉토리 명 변경 (Screen >> screen) * Feat: import 문 정리 * Rename: 패키지 명 변경 적용 * Rename: 패키지 명 변경 적용 * Design: padding 조절 * Fix: Response Dto 변경 * Feat: 환불 내역 조회 response 모델 추가 * Feat: response 변경에 따른 createAt 정보 추가 * Feat: navigation 이벤트 추가 * Feat: navigation 이벤트 추가 * Feat: order status 취소 완료 상태 추가 * Feat: order status 반품 완료 상태 추가 * Fix: UI 배송비 누락 수정 * Fix: UI 배송비 누락 수정 * Feat: 반품 완료 상태 추가 * Fix: 배송비 UI 누락 수정 * Design: UI 정렬 * Design: 버튼 삭제 * Remove: 미사용 화면 삭제 * Feat: NoDataPage >> EmptyDataPage 변경 * Design: font 적용 * Remove: 미사용 import 문 제거 * Rename: 파라미터 명 변경 * Feat: 반품 진행 중 상태 추가 * Feat: order status를 기준으로 Button UI 분기 * Feat: 반품 진행 중 상태 추가 * Feat: 리뷰 작성 navigation 이벤트 추가 * Comment: 임의 이벤트 주석 추가 * Rename: 파일 위치 이동 (like 모듈 >> userInfo 모듈) * Rename: navigation 이벤트 명 변경 * Feat: 좋아요 한 향수 화면 route 추가 * Feat: navigation 이벤트 추가 * Remove: like 모듈 삭제 및 user info 모듈 병합 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Ignore: git pull * Test: sort 로직 test * Feat: Paging 내 sort 추가 * Remove: 미사용 resource 삭제 * Fix: 카테고리 내용 변경 (시향기 >> 향BTI 시향기) * Refactor: 변수 위치 변경 * Revert * Ignore: git pull * Ignore: git pull * Feat: 리뷰 컴포넌트 추가 * Feat: 선택 시 사진 확대 추가 * Feat: 선택 시 사진 확대 추가 * Design: 색상 반전 여부 추가 * Feat: int RequestBody형으로 변환 함수 추가 * Chore: decode string 함수 의존성 추가 * Feat: 리뷰 관련 dto 추가 * Feat: photo dto 추가 * Feat: h shop review 관련 api 추가 * Feat: h shop review 관련 api 추가 * Feat: 좋아요 개수 파라미터 추가 * Design: 반전 여부 추가 * Feat: review 화면 추가 * Feat: path 변환 함수 (local uri >> absolute path) * Feat: get my orders api 추가 * Feat: get my orders dto 추가 * Feat: 리뷰 작성 view model 추가 * Feat: 리뷰 작성 화면 view model 연결 * Chore: json decode import 추가 * Feat: 리뷰 작성 navigation 추가 * Fix: FAB 버튼 파라미터 변경 (고정 값 >> 변동 값) * Rename: my orders api 위치 변경 (HShop >> HShopReview) * Feat: 파라미터 타입 변경 (() -> Unit >> Unit) * Feat: navigation 이벤트 추가 * Chore: paging 의존성 추가 * Fix: val >> var * Feat: 선택 가능 여부 설정 파라미터 추가 * Feat: paging 클래스 추가 * Feat: 리뷰 화면 view model 추가 * Feat: 리뷰 화면 view model 연결 * Feat: HBTI 홈 view model 추가 * Design: 테두리 색상 남는 UI 수정 * Design: navigation icon 색상 값 추가 * Style: 코드 스타일 변경 * Feat: navigation 이벤트 추가 * Design: 디자인 파라미터 변경 * Design: 글 색 변경 * Feat: 리뷰 UI 추가 * Design: FAB 디자인 변경 * Design: FAB padding 변경 * Design: icon 색상 변경 * Design: FAB 디자인 변경 * Design: text 변경 * Design: TopBar 색상 변경 * Design: FAB 선택 시 배경 애니메이션 추가 * Design: 컴포넌트 색상 명시 * Feat: 성능 개선을 위한 분리 * Fix: public >> private * Feat: 신고, 삭제 이름 선언 * Feat: 삭제, 신고 이벤트 추가 * Fix: ui 성능 개선 * Remove: 불필요 변수 제거 * Remove: 불필요 변수 제거 * Fix: var >> val * Fix: 좋아요 로직 변경 * Feat: navigation 이벤트 추가 * Chore: material 의존성 추가 * Feat: 좋아요 이벤트 추가 * Feat: 좋아요, 삭제, 신고 기능 추가 * Feat: 수정 api 추가 * Feat: 리뷰 수정 화면 추가 * Feat: 리뷰 수정 비즈니스 로직 추가 * Feat: 리뷰 수정 화면 네비게이션 연결 * Ignore * Design: FAB 버튼 테두리 삭제 * Fix: navigation 이벤트 호출 수정 * Feat: 리뷰 단건 조회, 삭제 api 추가 * Feat: FAB option 변수 값 변경 * Feat: delete review 함수 연결 * Fix: part 어노테이션 네이밍 오류 수정 * Fix: 함수 파라미터 변경 * Fix: 함수 파라미터 변경 * Feat: 삭제 후 ui 반영되도록 flag 추가 * Fix: delay 시간 축소 * Remove: log 삭제 * Design: 아이콘 변경 * Design: 스크롤 범위 전체로 변경 * Feat: 개별 navigation 람다 적용 * Feat: 개별 navigation 람다 적용 * Fix: Part 어노테이션 이름 추가 * Feat: 리뷰 수정 화면 navigation 연결 * Feat: single top 옵션 추가 * Design: 배경 이미지 추가 * Feat: 신고 기능 추가 * Feat: 리뷰 신고 api 추가 * Fix: 파라미터 명 변경 * Style: 코드 줄 변경 * Feat: 이벤트 후 dialog 닫기 * Feat: 작성한 리뷰 navigation 연결 * Rename: getMyOrders api 위치 이동 (hShopReview >> HShop) * Feat: 내가 작성한 review api 추가 * Feat: 내가 작성한 review 화면 추가 * Feat: 내가 작성한 review view model 추가 * Feat: 내 review paging source * Feat: 내 review 화면 연결 * Rename: paging source 위치 이동 * Feat: 리뷰 완료 상태 추가 * Feat: navigation 이벤트 추가 * Feat: createdAt 멤버 변수 추가 * Design: 클릭 범위 변경 * Design: 클릭 범위 변경 * Feat: navigation 파라미터 추가 * Feat: 환불 버튼 클릭 시 dialog 생성 * Design: fontSize, lineHeight 조정 * Design: 날짜 추가, 색상 변경 * Remove: 미사용 dto 삭제 * Fix: OrderStatus에 리뷰 완료 상태 >> isReviewed 멤버 변수로 변경 * Design: review 작성 여부와 order status에 따른 UI 변경 * Design: review 작성 여부와 order status에 따른 UI 변경 * Feat: navigation 이벤트 추가 * Design: 텍스트 문구 변경 * Fix: navigation 경로 수정 * Fix: review 사용 조건 변경 * Design: top bar 배경 색상 변경 * Refactor: 중복 함수 제거 * Fix: 닉네임 중복 확인 api 변경 반영 * Remove: 불필요 파라미터 제거 * Refactor: Recomposition 줄도록 수정 * Fix: 느린 상태 update 수정 * Fix: 느린 상태 update 수정 * Refactor: recomposition 감소 유도 * Ignore: Merge * Design: top bar 색상 추가 * Fix: 배송 요청을 선택 사항으로 변경 * Design: 단일 매거진 Pager로 변경 * Feat: ResultResponse Wrapping * Feat: nav login 네비게이션 이벤트 추가 * Refactor: Recomposition 감소 * Refactor: Recomposition 감소 * Feat: authenticator 추가 * Feat: authenticator 추가 * Style: 여백 삭제 * Design: 테두리 추가 * Refactor: Recomposition 감소 * Rename: 파라미터 명 변경 * Refactor: Recomposition 감소 * Refactor: Recomposition 감소 * Fix: NullPointerException 오류 수정 * Design: 버튼 색상 변경 * Design: 뒤고 가기 버튼 삭제 * Feat: navigation 도착지 변경 (홈 >> Hbti 홈) * Feat: navigation stack 정리 * Feat: navigation stack 정리 * Fix: Nickname Input 컴포넌트 파라미터 변경에 따른 수정 * Style: 중복 호출부 제거 * Refactor: Recomposition 감소 * Refactor: Recomposition 감소 * Refactor: LazyColumn 최적화 * Comment: 화면 내용 관련 주석 추가 * Design: text 추가 * Design: text 추가 * Fix: is enable 조건 변경 * Design: 글자 색상 변경 * Refactor: Recomposition 감소 * Ignore: git pull * Design: 안내 문구 추가 * Design: weight 수정 * Fix: 조건 수정 * Fix: 조건 수정 * Fix: buyer info 업데이트 안되느 오류 수정 --- .../main/java/com/hmoa/app/MainActivity.kt | 68 ++++----- .../java/com/hmoa/app/navigation/NavHost.kt | 81 +++++++++- .../core_designsystem/component/HomeTopBar.kt | 139 +++++++++++------- .../component/MainBottomBar.kt | 96 ++++++++---- .../component/OrderHistoryItem.kt | 38 +++-- .../feature_hbti/navigation/HbtiNavigation.kt | 11 +- .../feature_hbti/screen/AddAddressScreen.kt | 26 +++- .../hmoa/feature_hbti/screen/OrderScreen.kt | 59 ++++++-- .../feature_userinfo/Screen/MyBirthPage.kt | 23 +-- .../feature_userinfo/Screen/MyInfoPage.kt | 4 +- .../hmoa/feature_userinfo/Screen/MyPage.kt | 106 +++++++------ .../feature_userinfo/Screen/MyPostPage.kt | 19 ++- .../hmoa/feature_userinfo/Screen/MyReview.kt | 1 + .../feature_userinfo/Screen/NoAuthMyPage.kt | 4 +- .../Screen/OrderRecordPage.kt | 11 +- .../feature_userinfo/Screen/RefundPage.kt | 5 +- .../Screen/RefundRecordPage.kt | 30 +++- .../feature_userinfo/navigation/NavGraph.kt | 2 +- .../viewModel/MyGenderViewModel.kt | 35 +++-- 19 files changed, 491 insertions(+), 267 deletions(-) diff --git a/app/src/main/java/com/hmoa/app/MainActivity.kt b/app/src/main/java/com/hmoa/app/MainActivity.kt index b39f360f4..dabd29521 100644 --- a/app/src/main/java/com/hmoa/app/MainActivity.kt +++ b/app/src/main/java/com/hmoa/app/MainActivity.kt @@ -17,7 +17,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 @@ -36,7 +38,13 @@ 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.core_domain.entity.navigation.* +import com.hmoa.core_domain.entity.navigation.AuthenticationRoute +import com.hmoa.core_domain.entity.navigation.CommunityRoute +import com.hmoa.core_domain.entity.navigation.HPediaRoute +import com.hmoa.core_domain.entity.navigation.HomeRoute +import com.hmoa.core_domain.entity.navigation.MagazineRoute +import com.hmoa.core_domain.entity.navigation.PerfumeRoute +import com.hmoa.core_domain.entity.navigation.UserInfoRoute import com.hmoa.feature_brand.navigation.navigateToBrandSearch import com.hmoa.feature_fcm.navigateToAlarmScreen import com.hmoa.feature_home.navigation.navigateToHome @@ -70,15 +78,14 @@ class MainActivity : AppCompatActivity() { 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 val needTopBarScreens = HomeRoute.Home.name - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) installSplashScreen() @@ -105,21 +112,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) } @@ -127,28 +121,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( 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 8c5150beb..6268e878a 100644 --- a/app/src/main/java/com/hmoa/app/navigation/NavHost.kt +++ b/app/src/main/java/com/hmoa/app/navigation/NavHost.kt @@ -3,14 +3,61 @@ package com.hmoa.app.navigation import androidx.compose.runtime.Composable import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost -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_hbti.navigation.* -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 @@ -18,8 +65,30 @@ import com.hmoa.feature_hpedia.Navigation.nestedHPediaGraph 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_userinfo.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( 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/MainBottomBar.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/MainBottomBar.kt index c3698fa58..5a9267ff9 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 @@ -11,6 +11,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 +25,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 +35,86 @@ 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!! + } + } 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 +124,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/OrderHistoryItem.kt b/core-designsystem/src/main/java/com/hmoa/core_designsystem/component/OrderHistoryItem.kt index d3787e1fe..bf74e515c 100644 --- 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 @@ -212,7 +212,6 @@ private fun Buttons( ){ val buttonEnabled = shippingStatus == OrderStatus.SHIPPING_PROGRESS || shippingStatus == OrderStatus.SHIPPING_COMPLETE - OutlinedButton( modifier = Modifier.weight(1f), shape = RoundedCornerShape(3.dp), @@ -229,19 +228,32 @@ private fun Buttons( ) } Spacer(Modifier.width(20.dp)) - OutlinedButton( - modifier = Modifier.weight(1f), - 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), - ) { + 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( - text = "후기 작성", - fontSize = 12.sp, - color = if(!isReviewed) Color.Black else CustomColor.gray3, - fontFamily = CustomFont.semiBold + 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 ) } } diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/navigation/HbtiNavigation.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/navigation/HbtiNavigation.kt index 42fb13ae1..28b53880c 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/navigation/HbtiNavigation.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/navigation/HbtiNavigation.kt @@ -10,13 +10,13 @@ import com.hmoa.core_domain.entity.navigation.HbtiRoute import com.hmoa.core_domain.entity.navigation.HomeRoute import com.hmoa.core_model.data.NoteProductIds import com.hmoa.feature_hbti.screen.* +import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json fun NavController.navigateToHbti() = navigate("${HbtiRoute.Hbti}") { - popUpTo(HomeRoute.Home.name) { inclusive = false } + popUpTo(HomeRoute.Home.name){inclusive = false} launchSingleTop = true } - fun NavController.navigateToHbtiSurvey() = navigate("${HbtiRoute.HbtiSurvey}") { launchSingleTop = true } fun NavController.navigateToHbtiSurveyResult() = navigate("${HbtiRoute.HbtiSurveyResult}") { launchSingleTop = true } @@ -197,7 +197,6 @@ fun NavGraphBuilder.perfumeRecommendationResultRoute( ) } } - fun NavGraphBuilder.order( navBack: () -> Unit, navAddAddress: (String, String) -> Unit, @@ -239,8 +238,8 @@ fun NavGraphBuilder.addAddress( } } -fun NavGraphBuilder.orderResult(navHbti: () -> Unit) { - composable(route = HbtiRoute.OrderResultRoute.name) { +fun NavGraphBuilder.orderResult(navHbti: () -> Unit){ + composable(route = HbtiRoute.OrderResultRoute.name){ OrderResultRoute(navHbti = navHbti) } } @@ -294,4 +293,4 @@ fun NavGraphBuilder.editReview(navReview: (befRoute: HbtiRoute) -> Unit, navLogi navLogin = navLogin ) } -} +} \ No newline at end of file diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/AddAddressScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/AddAddressScreen.kt index f81e3b605..e1aa16ea5 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/AddAddressScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/AddAddressScreen.kt @@ -42,6 +42,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType +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 @@ -133,10 +134,11 @@ private fun AddAddressMainContent( var isEnabled = remember { derivedStateOf { name.isNotEmpty() && addressName.isNotEmpty() - && phone1.isNotEmpty() && phone2.isNotEmpty() && phone3.isNotEmpty() - && homePhone1.isNotEmpty() && homePhone2.isNotEmpty() && homePhone3.isNotEmpty() - && postalCode.isNotEmpty() && address.isNotEmpty() - && detailAddress.isNotEmpty() + && phone1.isNotEmpty() && phone2.isNotEmpty() && phone3.isNotEmpty() + && (homePhone1.isNotEmpty() && homePhone2.isNotEmpty() && homePhone3.isNotEmpty() + || homePhone1.isEmpty() && homePhone2.isEmpty() && homePhone3.isEmpty()) + && postalCode.isNotEmpty() && address.isNotEmpty() + && detailAddress.isNotEmpty() } } LaunchedEffect(Unit) { @@ -190,7 +192,7 @@ private fun AddAddressMainContent( modifier = Modifier .fillMaxSize() .verticalScroll(state = scrollState) - .padding(top = 20.dp) + .padding(top = 20.dp, bottom = 15.dp) .padding(horizontal = 16.dp) ) { Text( @@ -254,6 +256,18 @@ private fun AddAddressMainContent( }, radious = 5 ) + if(!isEnabled.value){ + Spacer(Modifier.height(13.dp)) + Text( + modifier = Modifier.fillMaxWidth(), + text = "내용이 올바르지 않거나, 입력하지 않은 항목이 있습니다.", + textAlign = TextAlign.Center, + fontSize = 12.sp, + lineHeight = 12.sp, + fontFamily = CustomFont.regular, + color = CustomColor.red + ) + } } } } @@ -453,7 +467,7 @@ private fun InputHomePhone( .padding(top = 16.dp) ) { Text( - text = "전화번호", + text = "전화번호(선택)", fontSize = 12.sp, fontFamily = CustomFont.medium ) diff --git a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/OrderScreen.kt b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/OrderScreen.kt index dc3250fef..b4aa15f77 100644 --- a/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/OrderScreen.kt +++ b/feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/OrderScreen.kt @@ -5,15 +5,36 @@ import android.webkit.WebView import android.webkit.WebViewClient import android.widget.Toast import androidx.activity.compose.BackHandler -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +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.size +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.text.KeyboardOptions +import androidx.compose.foundation.verticalScroll import androidx.compose.material3.HorizontalDivider 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.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 @@ -34,7 +55,13 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.hmoa.core_common.ErrorUiState import com.hmoa.core_common.concatWithComma import com.hmoa.core_common.formatWon -import com.hmoa.core_designsystem.component.* +import com.hmoa.core_designsystem.component.AppLoadingScreen +import com.hmoa.core_designsystem.component.Button +import com.hmoa.core_designsystem.component.CircleImageView +import com.hmoa.core_designsystem.component.CustomOutlinedTextField +import com.hmoa.core_designsystem.component.ErrorUiSetView +import com.hmoa.core_designsystem.component.TagBadge +import com.hmoa.core_designsystem.component.TopBar import com.hmoa.core_designsystem.theme.CustomColor import com.hmoa.core_designsystem.theme.CustomFont import com.hmoa.core_domain.entity.data.WebviewType @@ -547,11 +574,25 @@ private fun ProductInfo( .fillMaxWidth() .padding(top = 24.dp) ) { - Text( - text = "상품 정보", - fontSize = 18.sp, - fontFamily = CustomFont.bold - ) + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ){ + Text( + text = "상품 정보", + fontSize = 18.sp, + fontFamily = CustomFont.bold + ) + Text( + text = "11시 이전 결제 건까지 당일 발송", + fontSize = 11.sp, + lineHeight = 20.sp, + letterSpacing = (-0.4).sp, + fontFamily = CustomFont.regular, + color = CustomColor.gray4 + ) + } notes.forEach { note -> NoteItem(note = note, deleteNote = deleteNote) if (notes.lastIndex != notes.indexOf(note)) { diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyBirthPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyBirthPage.kt index 20749c5ec..fad212bd6 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyBirthPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyBirthPage.kt @@ -1,12 +1,7 @@ package com.hmoa.feature_userinfo.screen import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Column -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.* import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ModalBottomSheetLayout import androidx.compose.material.ModalBottomSheetValue @@ -31,12 +26,7 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.hmoa.core_common.ErrorUiState import com.hmoa.core_designsystem.R -import com.hmoa.core_designsystem.component.AppLoadingScreen -import com.hmoa.core_designsystem.component.Button -import com.hmoa.core_designsystem.component.ErrorUiSetView -import com.hmoa.core_designsystem.component.Spinner -import com.hmoa.core_designsystem.component.TopBar -import com.hmoa.core_designsystem.component.YearPickerDialog +import com.hmoa.core_designsystem.component.* import com.hmoa.core_designsystem.theme.CustomColor import com.hmoa.feature_userinfo.viewModel.MyBirthUiState import com.hmoa.feature_userinfo.viewModel.MyBirthViewModel @@ -111,13 +101,6 @@ private fun SelectBirthContent( ModalBottomSheetLayout( sheetState = modalSheetState, sheetContent = { -// Column( -// modifier = Modifier -// .fillMaxHeight() -// .background(CustomColor.gray4), -// verticalArrangement = Arrangement.Bottom -// ) { -// } YearPickerDialog( yearList = availableYearRange, initialValue = initBirth, @@ -182,4 +165,4 @@ fun BrithTest(){ SelectBirthContent( initBirth = initBirth, saveBirth = { }, navBack = {} ) -} +} \ No newline at end of file diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyInfoPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyInfoPage.kt index 9fc83f5a1..57c7418fb 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyInfoPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyInfoPage.kt @@ -51,7 +51,7 @@ fun MyInfoPage( .background(color = Color.White) ){ TopBar( - navIcon = painterResource(com.hmoa.core_designsystem.R.drawable.ic_back), + navIcon = painterResource(R.drawable.ic_back), onNavClick = navBack, //뒤오 가기 title = "내 정보" ) @@ -66,7 +66,7 @@ fun MyInfoPage( ){ Text( text = "출생연도", - fontFamily = FontFamily(Font(com.hmoa.core_designsystem.R.font.pretendard_regular)), + fontFamily = FontFamily(Font(R.font.pretendard_regular)), fontSize = 16.sp, ) Icon( diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyPage.kt index a0955b0d8..fe1d54890 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyPage.kt @@ -12,7 +12,15 @@ import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts 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.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.material.icons.Icons @@ -21,7 +29,12 @@ import androidx.compose.material3.HorizontalDivider 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.rememberCoroutineScope +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -40,7 +53,11 @@ import com.google.android.gms.oss.licenses.OssLicensesMenuActivity import com.hmoa.core_common.ErrorUiState import com.hmoa.core_common.checkPermission import com.hmoa.core_designsystem.R -import com.hmoa.core_designsystem.component.* +import com.hmoa.core_designsystem.component.AppLoadingScreen +import com.hmoa.core_designsystem.component.CircleImageView +import com.hmoa.core_designsystem.component.ErrorUiSetView +import com.hmoa.core_designsystem.component.OnAndOffBtn +import com.hmoa.core_designsystem.component.TopBar import com.hmoa.core_designsystem.theme.CustomColor import com.hmoa.core_domain.entity.data.ColumnData import com.hmoa.core_domain.entity.navigation.UserInfoRoute @@ -65,29 +82,47 @@ internal fun MyPageRoute( viewModel: MyPageViewModel = hiltViewModel() ) { val context = LocalContext.current + val scope = rememberCoroutineScope() + val launcher = rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) {} + val isLogin = viewModel.isLogin.collectAsStateWithLifecycle(false) val isEnabledAlarm = viewModel.isEnabled.collectAsStateWithLifecycle() - val onChangeAlarm: (Boolean) -> Unit = { - if (checkPermission(context, Manifest.permission.POST_NOTIFICATIONS)) { - viewModel.changeAlarmSetting(it) - } else { - Toast.makeText(context, "알림 권한이 없습니다.\n알림 권한을 설정해주세요.", Toast.LENGTH_SHORT).show() - } - } val uiState = viewModel.uiState.collectAsStateWithLifecycle() val errorUiState by viewModel.errorUiState.collectAsStateWithLifecycle() + val privacyPolicyIntent = remember { Intent(Intent.ACTION_VIEW, Uri.parse(BuildConfig.PRIVACY_POLICY_URI)) } + val termsOfServiceIntent = remember { Intent(Intent.ACTION_VIEW, Uri.parse(BuildConfig.TERMS_OF_SERVICE)) } + + + val onChangeAlarm: (Boolean) -> Unit = { + if (checkPermission(context, Manifest.permission.POST_NOTIFICATIONS)) { viewModel.changeAlarmSetting(it) } + else { Toast.makeText(context, "알림 권한이 없습니다.\n알림 권한을 설정해주세요.", Toast.LENGTH_SHORT).show() } + } val navKakao = { TalkApiClient.instance.chatChannel(context, BuildConfig.KAKAO_CHAT_PROFILE) { err -> - if (err != null) { - Toast.makeText(context, "향모아 챗봇 오류가 발생했습니다:(", Toast.LENGTH_LONG).show() - } + if (err != null) { Toast.makeText(context, "향모아 챗봇 오류가 발생했습니다:(", Toast.LENGTH_LONG).show() } } } - val launcher = rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) {} + val navOrderRecord = remember{{navOrderRecord(UserInfoRoute.MyPage)}} + + val openLicenses = remember{{ + launcher.launch(Intent(context, OssLicensesMenuActivity::class.java)) + OssLicensesMenuActivity.setActivityTitle("오픈소스 라이센스") + }} + val logout: () -> Unit = remember{{ + scope.launch { + launch { viewModel.logout() }.join() + navLogin() + } + }} + val deleteAccount: () -> Unit = remember{{ + scope.launch { + launch { viewModel.delAccount() }.join() + navLogin() + } + }} + val openPrivacyPolicyLink = remember{{context.startActivity(privacyPolicyIntent) }} + val openTermsOfServiceLink = remember{{context.startActivity(termsOfServiceIntent) }} - val privacyPolicyIntent = remember { Intent(Intent.ACTION_VIEW, Uri.parse(BuildConfig.PRIVACY_POLICY_URI)) } - val termsOfServiceIntent = remember { Intent(Intent.ACTION_VIEW, Uri.parse(BuildConfig.TERMS_OF_SERVICE)) } - val scope = rememberCoroutineScope() if (isLogin.value) { //로그인 분기 처리 (토큰 확인) MyPage( @@ -96,24 +131,11 @@ internal fun MyPageRoute( appVersion = appVersion, isEnabledAlarm = isEnabledAlarm.value, onChangeAlarm = onChangeAlarm, - logoutEvent = { - scope.launch { - launch { viewModel.logout() }.join() - navLogin() - } - }, - doOpenLicense = { - launcher.launch(Intent(context, OssLicensesMenuActivity::class.java)) - OssLicensesMenuActivity.setActivityTitle("오픈소스 라이센스") - }, - openPrivacyPolicyLink = { context.startActivity(privacyPolicyIntent) }, - openTermsOfServiceLink = { context.startActivity(termsOfServiceIntent) }, - onDelAccount = { - scope.launch { - launch { viewModel.delAccount() }.join() - navLogin() - } - }, + logoutEvent = logout, + openLicenses = openLicenses, + openPrivacyPolicyLink = openPrivacyPolicyLink, + openTermsOfServiceLink = openTermsOfServiceLink, + onDelAccount = deleteAccount, onNavKakaoChat = navKakao, navMyPerfume = navMyPerfume, navEditProfile = navEditProfile, @@ -139,9 +161,9 @@ fun MyPage( errorUiState: ErrorUiState, appVersion: String, isEnabledAlarm: Boolean, - onChangeAlarm: (Boolean) -> Unit, + onChangeAlarm: (isEnabledAlarm: Boolean) -> Unit, logoutEvent: () -> Unit, - doOpenLicense: () -> Unit, + openLicenses: () -> Unit, onDelAccount: () -> Unit, openPrivacyPolicyLink: () -> Unit, openTermsOfServiceLink: () -> Unit, @@ -166,7 +188,7 @@ fun MyPage( isEnabledAlarm = isEnabledAlarm, onChangeAlarm = onChangeAlarm, logoutEvent = logoutEvent, - doOpenLicense = doOpenLicense, + doOpenLicense = openLicenses, openPrivacyPolicyLink = openPrivacyPolicyLink, openTermsOfServiceLink = openTermsOfServiceLink, onDelAccount = onDelAccount, @@ -200,7 +222,7 @@ private fun MyPageContent( provider: String, appVersion: String, isEnabledAlarm: Boolean, - onChangeAlarm: (Boolean) -> Unit, + onChangeAlarm: (isEnabledAlarm: Boolean) -> Unit, logoutEvent: () -> Unit, doOpenLicense: () -> Unit, openPrivacyPolicyLink: () -> Unit, @@ -255,7 +277,7 @@ private fun MyPageContent( provider = provider, navEditProfile = navEditProfile ) - //ServiceAlarm() + ServiceAlarm(isEnabledAlarm = isEnabledAlarm, onChangeAlarm = onChangeAlarm) HorizontalDivider(thickness = 1.dp, color = CustomColor.gray2) } @@ -282,9 +304,7 @@ private fun MyPageContent( tint = CustomColor.gray2 ) } - if (idx % 3 == 2) { - HorizontalDivider(thickness = 1.dp, color = CustomColor.gray2) - } + if (idx % 3 == 2) { HorizontalDivider(thickness = 1.dp, color = CustomColor.gray2) } } } } diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyPostPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyPostPage.kt index 6761bc1d0..7c6ca735d 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyPostPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyPostPage.kt @@ -11,6 +11,7 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource @@ -28,16 +29,17 @@ import com.hmoa.core_model.response.CommunityByCategoryResponseDto import com.hmoa.feature_userinfo.viewModel.PostUiState import com.hmoa.feature_userinfo.viewModel.PostViewModel +//내 게시글 화면 @Composable fun MyPostRoute( navBack: () -> Unit, navEditPost: (Int) -> Unit, viewModel : PostViewModel = hiltViewModel() ) { - val uiState = viewModel.uiState.collectAsStateWithLifecycle() + val uiState by viewModel.uiState.collectAsStateWithLifecycle() MyPostPage( - uiState = uiState.value, + uiState = uiState, navBack = navBack, navEditPost = navEditPost, ) @@ -59,10 +61,7 @@ fun MyPostPage( navEditPost = navEditPost ) } - PostUiState.Error -> { - - } - else -> {} + PostUiState.Error -> {} } } @@ -83,7 +82,8 @@ private fun MyPostContent( onNavClick = navBack ) Column( - modifier = Modifier.fillMaxSize() + modifier = Modifier + .fillMaxSize() .padding(horizontal = 16.dp) .padding(top = 8.dp) ){ @@ -93,7 +93,10 @@ private fun MyPostContent( .fillMaxWidth() .weight(1f) ) { - items(posts) { post -> + items( + items = posts, + key = {item -> item?.communityId!!} + ) { post -> if (post != null){ PostListItem( modifier = Modifier diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyReview.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyReview.kt index 2987b52b7..a3ac6a615 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyReview.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyReview.kt @@ -27,6 +27,7 @@ import com.hmoa.core_model.response.ReviewResponseDto import com.hmoa.feature_userinfo.viewModel.MyReviewUiState import com.hmoa.feature_userinfo.viewModel.MyReviewViewModel +// 내가 작성한 review 화면 @Composable fun MyReviewRoute( navReview: (befRoute: HbtiRoute) -> Unit, diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/NoAuthMyPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/NoAuthMyPage.kt index 806f636c2..37158c9c3 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/NoAuthMyPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/NoAuthMyPage.kt @@ -28,9 +28,7 @@ import com.hmoa.core_designsystem.theme.CustomColor //인증이 안되어 있는 My Page @Composable -fun NoAuthMyPage( - navLogin: () -> Unit, -) { +fun NoAuthMyPage(navLogin: () -> Unit) { Column( modifier = Modifier .fillMaxSize() diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/OrderRecordPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/OrderRecordPage.kt index 0dd84d2dd..8197c49a6 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/OrderRecordPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/OrderRecordPage.kt @@ -18,7 +18,11 @@ import androidx.paging.ItemSnapshotList import androidx.paging.compose.collectAsLazyPagingItems import com.hmoa.core_common.ErrorUiState import com.hmoa.core_designsystem.R -import com.hmoa.core_designsystem.component.* +import com.hmoa.core_designsystem.component.AppLoadingScreen +import com.hmoa.core_designsystem.component.EmptyDataPage +import com.hmoa.core_designsystem.component.ErrorUiSetView +import com.hmoa.core_designsystem.component.OrderRecordItem +import com.hmoa.core_designsystem.component.TopBar import com.hmoa.core_model.response.OrderRecordDto import com.hmoa.feature_userinfo.viewModel.OrderRecordUiState import com.hmoa.feature_userinfo.viewModel.OrderRecordViewModel @@ -100,7 +104,10 @@ fun OrderRecordContent( LazyColumn( modifier = Modifier.fillMaxSize() ) { - items(data) { order -> + items( + items = data, + key = {item -> item!!.orderId} + ) { order -> if (order != null) { OrderRecordItem( shippingType = order.orderStatus, diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/RefundPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/RefundPage.kt index c239d999a..5fa61b943 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/RefundPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/RefundPage.kt @@ -18,6 +18,7 @@ import androidx.compose.foundation.lazy.items import androidx.compose.material3.HorizontalDivider 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 @@ -86,7 +87,7 @@ fun RefundRoute( uiState = uiState.value, errState = errState.value, type = type!!, - doRefund = { viewModel.refundOrder() }, + doRefund = viewModel::refundOrder, navBack = navBack, navLogin = navLogin ) @@ -297,4 +298,4 @@ private fun ReturnOrRefundUITest(){ navBack = {}, navLogin = {} ) -} +} \ No newline at end of file diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/RefundRecordPage.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/RefundRecordPage.kt index b898ae270..58a50181e 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/RefundRecordPage.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/RefundRecordPage.kt @@ -1,12 +1,21 @@ package com.hmoa.feature_userinfo.screen import androidx.compose.foundation.background -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.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.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -20,7 +29,11 @@ import androidx.paging.ItemSnapshotList import androidx.paging.compose.collectAsLazyPagingItems import com.hmoa.core_common.ErrorUiState import com.hmoa.core_common.toDisplayString -import com.hmoa.core_designsystem.component.* +import com.hmoa.core_designsystem.component.AppLoadingScreen +import com.hmoa.core_designsystem.component.EmptyDataPage +import com.hmoa.core_designsystem.component.ErrorUiSetView +import com.hmoa.core_designsystem.component.NoteListItem +import com.hmoa.core_designsystem.component.TopBar import com.hmoa.core_designsystem.theme.CustomColor import com.hmoa.core_designsystem.theme.CustomFont import com.hmoa.core_model.response.FinalOrderResponseDto @@ -35,13 +48,13 @@ fun RefundRecordRoute( navLogin: () -> Unit, viewModel: RefundRecordViewModel = hiltViewModel() ) { - val uiState = viewModel.uiState.collectAsStateWithLifecycle() - val errState = viewModel.errorUiState.collectAsStateWithLifecycle() + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + val errState by viewModel.errorUiState.collectAsStateWithLifecycle() RefundRecordScreen( navBack = navBack, navLogin = navLogin, - uiState = uiState.value, - errState = errState.value, + uiState = uiState, + errState = errState, ) } @@ -94,7 +107,10 @@ private fun RefundRecordContent( ) { if (data.isNotEmpty()) { LazyColumn { - items(data) { record -> + items( + items = data, + key = {item -> item?.orderId!!} + ) { record -> if (record != null) { ReturnOrRefundRecordItem( status = record.orderStatus.toDisplayString(), diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/navigation/NavGraph.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/navigation/NavGraph.kt index 26c2bdc4c..4a6b3fa2d 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/navigation/NavGraph.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/navigation/NavGraph.kt @@ -195,4 +195,4 @@ fun NavGraphBuilder.nestedUserInfoGraph( MyReviewRoute(navReview = navReview, navBack = navBack, navLogin = navLogin) } } -} +} \ No newline at end of file diff --git a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyGenderViewModel.kt b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyGenderViewModel.kt index de1b24137..25e9ca8f3 100644 --- a/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyGenderViewModel.kt +++ b/feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyGenderViewModel.kt @@ -7,6 +7,13 @@ import com.hmoa.core_domain.repository.MemberRepository import com.hmoa.core_domain.usecase.GetMyUserInfoUseCase import com.hmoa.core_model.request.SexRequestDto import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import javax.inject.Inject @@ -37,25 +44,23 @@ class MyGenderViewModel @Inject constructor( started = SharingStarted.WhileSubscribed(5_000), initialValue = ErrorUiState.Loading ) - val uiState: StateFlow = errorUiState.map { errState -> + val uiState: StateFlow = errorUiState.map {errState -> if (errState is ErrorUiState.ErrorData && errState.isValidate()) throw Exception("") val result = getMyUserInfoUseCase() - if (result.errorMessage != null) { - throw Exception(result.errorMessage!!.message) - } + if (result.errorMessage != null) {throw Exception(result.errorMessage!!.message)} result.data }.asResult().map { result -> when (result) { Result.Loading -> MyGenderUiState.Loading is Result.Success -> MyGenderUiState.Success(result.data!!.gender) is Result.Error -> { - if (result.exception.message != "") { + if (result.exception.message != ""){ handleErrorType( error = result.exception, onExpiredTokenError = { expiredTokenErrorState.update { true } }, - onWrongTypeTokenError = { wrongTypeTokenErrorState.update { true } }, - onUnknownError = { unLoginedErrorState.update { true } }, - onGeneralError = { generalErrorState.update { Pair(true, result.exception.message) } } + onWrongTypeTokenError = { wrongTypeTokenErrorState.update{true}}, + onUnknownError = {unLoginedErrorState.update{true}}, + onGeneralError = {generalErrorState.update{Pair(true, result.exception.message)}} ) } MyGenderUiState.Error @@ -72,12 +77,12 @@ class MyGenderViewModel @Inject constructor( val requestDto = SexRequestDto(gender == "남성") viewModelScope.launch { val result = memberRepository.updateSex(requestDto) - if (result.errorMessage != null) { - when (result.errorMessage!!.message) { - ErrorMessageType.UNKNOWN_ERROR.name -> unLoginedErrorState.update { true } - ErrorMessageType.WRONG_TYPE_TOKEN.name -> wrongTypeTokenErrorState.update { true } - ErrorMessageType.EXPIRED_TOKEN.name -> expiredTokenErrorState.update { true } - else -> generalErrorState.update { Pair(true, result.errorMessage!!.message) } + if (result.errorMessage != null){ + when(result.errorMessage!!.message){ + ErrorMessageType.UNKNOWN_ERROR.name -> unLoginedErrorState.update{true} + ErrorMessageType.WRONG_TYPE_TOKEN.name -> wrongTypeTokenErrorState.update{true} + ErrorMessageType.EXPIRED_TOKEN.name -> expiredTokenErrorState.update{true} + else -> generalErrorState.update{Pair(true, result.errorMessage!!.message)} } return@launch } @@ -93,4 +98,4 @@ sealed interface MyGenderUiState { ) : MyGenderUiState data object Error : MyGenderUiState -} +} \ No newline at end of file From 7e58fce5ce8b9b0baa32100de75fce5766571a31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Sat, 23 Nov 2024 02:13:49 +0900 Subject: [PATCH 39/93] =?UTF-8?q?Chore:=20=EB=B2=84=EC=A0=84=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EB=B3=80=EA=B2=BD=2028->30?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c3b2da1a9..19a42a668 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -22,7 +22,7 @@ android { applicationId = "com.hmoa.app" minSdk = 26 targetSdk = 34 - versionCode = 28 + versionCode = 30 versionName = "1.1.4" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" From 71e93a98187223f1d4662be549dbf16dff2cf527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Mon, 2 Dec 2024 00:33:17 +0900 Subject: [PATCH 40/93] =?UTF-8?q?Feat:=20SearchTopBar=20Debounce=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/SearchTopBar.kt | 49 ++++++++-------- .../screen/PerfumeSearchScreen.kt | 56 +++++++++---------- .../viewmodel/PerfumeSearchViewmodel.kt | 13 ++++- 3 files changed, 61 insertions(+), 57 deletions(-) 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..df1bc0f52 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.isNotEmpty() }.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/feature-home/src/main/java/com/hmoa/feature_home/screen/PerfumeSearchScreen.kt b/feature-home/src/main/java/com/hmoa/feature_home/screen/PerfumeSearchScreen.kt index 0d1ef4f92..fd45d1f21 100644 --- a/feature-home/src/main/java/com/hmoa/feature_home/screen/PerfumeSearchScreen.kt +++ b/feature-home/src/main/java/com/hmoa/feature_home/screen/PerfumeSearchScreen.kt @@ -3,13 +3,7 @@ package com.hmoa.feature_home.screen import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.background import androidx.compose.foundation.clickable -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.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid @@ -61,11 +55,7 @@ fun PerfumeSearchScreen( perfumeNameSearchResult = perfumeNameSearchResult, perfumeSearchResult = perfumeSearchResult, viewType = viewType.value, - onChangedWord = { - viewModel.updatePerfumeNameSearchWord(it) - viewModel.updatePerfumeSearchWord(it) - perfumeNameSearchResult?.refresh() - }, + onChangedWord = { viewModel.handlePerfumeNameChange(it) }, onClearWord = { viewModel.updatePerfumeNameSearchWord(word = "") viewModel.changeViewType(PerfumeSearchViewType.List) @@ -109,22 +99,32 @@ fun PerfumeSearchContent( ) } Spacer(modifier = Modifier.fillMaxWidth().height(1.dp).background(color = CustomColor.gray2)) - Column( - modifier = Modifier.fillMaxWidth().padding(vertical = 10.dp).background(Color.White), - horizontalAlignment = Alignment.CenterHorizontally - ) { - when (viewType) { - PerfumeSearchViewType.List -> { - PerfumeNameSearchResultList( - perfumeNameList = perfumeNameSearchResult, - onPerfumeSearchResultClick = { onPerfumeSearchResultClick(it) }) - } + PerfumeSearchView(viewType, perfumeNameSearchResult, perfumeSearchResult, onPerfumeSearchResultClick) + } +} - PerfumeSearchViewType.Grid -> { - PerfumeSearchResultList( - perfumeList = perfumeSearchResult, - onPerfumeSearchResultClick = { onPerfumeSearchResultClick(it) }) - } +@Composable +fun PerfumeSearchView( + viewType: PerfumeSearchViewType, + perfumeNameSearchResult: LazyPagingItems?, + perfumeSearchResult: LazyPagingItems?, + onPerfumeSearchResultClick: (searchWord: String) -> Unit, +) { + Column( + modifier = Modifier.fillMaxWidth().padding(vertical = 10.dp).background(Color.White), + horizontalAlignment = Alignment.CenterHorizontally + ) { + when (viewType) { + PerfumeSearchViewType.List -> { + PerfumeNameSearchResultList( + perfumeNameList = perfumeNameSearchResult, + onPerfumeSearchResultClick = { onPerfumeSearchResultClick(it) }) + } + + PerfumeSearchViewType.Grid -> { + PerfumeSearchResultList( + perfumeList = perfumeSearchResult, + onPerfumeSearchResultClick = { onPerfumeSearchResultClick(it) }) } } } @@ -233,4 +233,4 @@ fun PerfumeSearchScreenPreview() { onPerfumeSearchResultClick = {}, onBackClick = {} ) -} \ No newline at end of file +} diff --git a/feature-home/src/main/java/com/hmoa/feature_home/viewmodel/PerfumeSearchViewmodel.kt b/feature-home/src/main/java/com/hmoa/feature_home/viewmodel/PerfumeSearchViewmodel.kt index c9953f8e5..10f3ffe74 100644 --- a/feature-home/src/main/java/com/hmoa/feature_home/viewmodel/PerfumeSearchViewmodel.kt +++ b/feature-home/src/main/java/com/hmoa/feature_home/viewmodel/PerfumeSearchViewmodel.kt @@ -7,12 +7,12 @@ import androidx.paging.Pager import androidx.paging.PagingConfig import androidx.paging.PagingData import androidx.paging.cachedIn +import com.hmoa.core_domain.entity.data.PerfumeSearchViewType import com.hmoa.core_domain.repository.SearchRepository import com.hmoa.core_model.response.PerfumeNameSearchResponseDto import com.hmoa.core_model.response.PerfumeSearchResponseDto import com.hmoa.feature_home.PerfumeNameSearchPagingSource import com.hmoa.feature_home.PerfumeSearchPagingSource -import com.hmoa.core_domain.entity.data.PerfumeSearchViewType import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow @@ -27,9 +27,16 @@ class PerfumeSearchViewmodel @Inject constructor(private val searchRepository: S private var _perfumeSearchWordState = MutableStateFlow(null) val perfumeSearchWordState: StateFlow = _perfumeSearchWordState private var _searchResultViewType = MutableStateFlow( - PerfumeSearchViewType.List) + PerfumeSearchViewType.List + ) val searchResultViewType: StateFlow = _searchResultViewType + fun handlePerfumeNameChange(word: String) { + updatePerfumeNameSearchWord(word) + updatePerfumeSearchWord(word) + getPagingPerfumeNameSearchResults() + } + fun perfumeNameSearchPagingSource(word: String) = PerfumeNameSearchPagingSource(searchRepository, word) fun perfumeSearchPagingSource(word: String) = PerfumeSearchPagingSource(searchRepository, word) @@ -65,4 +72,4 @@ class PerfumeSearchViewmodel @Inject constructor(private val searchRepository: S fun changeViewType(viewType: PerfumeSearchViewType) { _searchResultViewType.update { viewType } } -} \ No newline at end of file +} From c1b72484909bd03f0f3e729702e99bfc2cb33509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Mon, 2 Dec 2024 00:36:20 +0900 Subject: [PATCH 41/93] =?UTF-8?q?Fix:=20Debounce=20=ED=95=84=ED=84=B0?= =?UTF-8?q?=EB=A7=81=20=EC=A1=B0=EA=B1=B4=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/hmoa/core_designsystem/component/SearchTopBar.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 df1bc0f52..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 @@ -40,7 +40,7 @@ fun SearchTopBar( val textFlow = remember { snapshotFlow { searchWord } } LaunchedEffect(textFlow) { - textFlow.debounce(700).filter { it.isNotEmpty() }.collect { onChangeWord(it) } + textFlow.debounce(700).filter { it.isNotBlank() }.collect { onChangeWord(it) } } TopAppBar( From b9ec5e417871ac40907e93689ca83dcc86162e20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Mon, 2 Dec 2024 00:41:46 +0900 Subject: [PATCH 42/93] =?UTF-8?q?Design:=20=ED=99=88=20=EA=B8=80=EC=94=A8?= =?UTF-8?q?=20align=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/hmoa/feature_home/screen/HomeScreen.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/feature-home/src/main/java/com/hmoa/feature_home/screen/HomeScreen.kt b/feature-home/src/main/java/com/hmoa/feature_home/screen/HomeScreen.kt index 79dc85692..2cf324e73 100644 --- a/feature-home/src/main/java/com/hmoa/feature_home/screen/HomeScreen.kt +++ b/feature-home/src/main/java/com/hmoa/feature_home/screen/HomeScreen.kt @@ -315,9 +315,10 @@ private fun FirstMenuView(firstMenu: HomeMenuDefaultResponseDto, onPerfumeClick: fontSize = 14.sp, fontWeight = FontWeight.Medium, modifier = Modifier - .padding(horizontal = 16.dp) + .padding(horizontal = 16.dp).fillMaxWidth() .padding(vertical = 12.dp), - fontFamily = CustomFont.regular + fontFamily = CustomFont.regular, + textAlign = TextAlign.Start, ) Row( modifier = Modifier From 9977649e32043cc34f49d447a537cbe2641422f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Mon, 2 Dec 2024 04:05:02 +0900 Subject: [PATCH 43/93] =?UTF-8?q?Design:=20=ED=96=A5=EC=88=98=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=ED=8C=A8=EB=94=A9=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hmoa/feature_home/screen/HomeScreen.kt | 22 +++++++++++-------- .../feature_perfume/screen/PerfumeScreen.kt | 3 ++- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/feature-home/src/main/java/com/hmoa/feature_home/screen/HomeScreen.kt b/feature-home/src/main/java/com/hmoa/feature_home/screen/HomeScreen.kt index 79dc85692..b2fc80858 100644 --- a/feature-home/src/main/java/com/hmoa/feature_home/screen/HomeScreen.kt +++ b/feature-home/src/main/java/com/hmoa/feature_home/screen/HomeScreen.kt @@ -316,8 +316,9 @@ private fun FirstMenuView(firstMenu: HomeMenuDefaultResponseDto, onPerfumeClick: fontWeight = FontWeight.Medium, modifier = Modifier .padding(horizontal = 16.dp) - .padding(vertical = 12.dp), - fontFamily = CustomFont.regular + .padding(vertical = 12.dp).fillMaxWidth(), + fontFamily = CustomFont.regular, + textAlign = TextAlign.Start ) Row( modifier = Modifier @@ -439,16 +440,19 @@ fun ImageWithTitleView( Box( modifier = Modifier .clickable { onItemClick() } + .background(color = CustomColor.gray8) .fillMaxWidth(containerWidth) .fillMaxHeight(containerHeight), contentAlignment = Alignment.BottomStart ) { - ImageView( - imageUrl, - width = width, - height = height, - backgroundColor = CustomColor.gray8, - contentScale = ContentScale.Fit - ) + Column(modifier = Modifier.padding(20.dp).background(color = CustomColor.gray8)) { + ImageView( + imageUrl, + width = width, + height = height, + backgroundColor = CustomColor.gray8, + contentScale = ContentScale.Fit + ) + } Text( text = title, fontWeight = FontWeight.SemiBold, diff --git a/feature-perfume/src/main/java/com/hmoa/feature_perfume/screen/PerfumeScreen.kt b/feature-perfume/src/main/java/com/hmoa/feature_perfume/screen/PerfumeScreen.kt index 0cdb323f7..74a3f2db3 100644 --- a/feature-perfume/src/main/java/com/hmoa/feature_perfume/screen/PerfumeScreen.kt +++ b/feature-perfume/src/main/java/com/hmoa/feature_perfume/screen/PerfumeScreen.kt @@ -208,7 +208,8 @@ fun PerfumeContent( onMenuClick = { onHomeClick() } ) Column( - modifier = Modifier.fillMaxWidth().heightIn(360.dp).background(color = CustomColor.gray2), + modifier = Modifier.fillMaxWidth().heightIn(360.dp).background(color = CustomColor.gray2) + .padding(vertical = 20.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { From 455fd1e80548633e44565664875330a9f57cab9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Mon, 2 Dec 2024 04:08:32 +0900 Subject: [PATCH 44/93] =?UTF-8?q?Chore:=20=EB=B2=84=EC=A0=84=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EB=B3=80=EA=B2=BD=2030->31?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 19a42a668..4dad643ea 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -22,7 +22,7 @@ android { applicationId = "com.hmoa.app" minSdk = 26 targetSdk = 34 - versionCode = 30 + versionCode = 31 versionName = "1.1.4" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" From b074256d28ad633a121b91a51e0162f2313b5a10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Tue, 3 Dec 2024 17:00:33 +0900 Subject: [PATCH 45/93] =?UTF-8?q?HotFix:=20nullable=20=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=20=EC=86=8D=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/deploymentTargetSelector.xml | 4 +- .../response/RecentPerfumeResponseDtoItem.kt | 7 +- .../feature_magazine/Screen/MagazineMain.kt | 130 ++++++++---------- 3 files changed, 64 insertions(+), 77 deletions(-) diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml index 9f9d13654..4c3ff026b 100644 --- a/.idea/deploymentTargetSelector.xml +++ b/.idea/deploymentTargetSelector.xml @@ -4,7 +4,7 @@ - + \ No newline at end of file diff --git a/core-model/src/main/java/com/hmoa/core_model/response/RecentPerfumeResponseDtoItem.kt b/core-model/src/main/java/com/hmoa/core_model/response/RecentPerfumeResponseDtoItem.kt index 885c5ed5a..1fd9eaf87 100644 --- a/core-model/src/main/java/com/hmoa/core_model/response/RecentPerfumeResponseDtoItem.kt +++ b/core-model/src/main/java/com/hmoa/core_model/response/RecentPerfumeResponseDtoItem.kt @@ -1,9 +1,12 @@ package com.hmoa.core_model.response +import kotlinx.serialization.Serializable + +@Serializable data class RecentPerfumeResponseDtoItem( val brandName: String, val perfumeId: Int, val perfumeImgUrl: String, val perfumeName: String, - val relaseDate: String -) \ No newline at end of file + val releaseDate: String? +) diff --git a/feature-magazine/src/main/java/com/hmoa/feature_magazine/Screen/MagazineMain.kt b/feature-magazine/src/main/java/com/hmoa/feature_magazine/Screen/MagazineMain.kt index 5a2eadc21..6ebca983f 100644 --- a/feature-magazine/src/main/java/com/hmoa/feature_magazine/Screen/MagazineMain.kt +++ b/feature-magazine/src/main/java/com/hmoa/feature_magazine/Screen/MagazineMain.kt @@ -4,20 +4,7 @@ import androidx.compose.foundation.ExperimentalFoundationApi 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 -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.aspectRatio -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.layout.wrapContentSize +import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items @@ -43,11 +30,7 @@ import androidx.paging.compose.LazyPagingItems import androidx.paging.compose.collectAsLazyPagingItems import com.hmoa.core_common.ErrorUiState import com.hmoa.core_designsystem.R -import com.hmoa.core_designsystem.component.AppLoadingScreen -import com.hmoa.core_designsystem.component.CircleImageView -import com.hmoa.core_designsystem.component.ErrorUiSetView -import com.hmoa.core_designsystem.component.ImageView -import com.hmoa.core_designsystem.component.TopBar +import com.hmoa.core_designsystem.component.* import com.hmoa.core_designsystem.theme.CustomColor import com.hmoa.core_model.response.MagazineSummaryResponseDto import com.hmoa.core_model.response.MagazineTastingCommentResponseDto @@ -87,8 +70,8 @@ fun MagazineMainScreen( onNavPerfumeDesc: (Int) -> Unit, onNavCommunityDesc: (Int) -> Unit, onNavMagazineDesc: (Int) -> Unit -){ - when(uiState){ +) { + when (uiState) { MagazineMainUiState.Loading -> AppLoadingScreen() is MagazineMainUiState.MagazineMain -> { MagazineFullContent( @@ -113,21 +96,21 @@ fun MagazineMainScreen( @Composable private fun MagazineFullContent( - magazineList : ItemSnapshotList, - perfumeList : RecentPerfumeResponseDto, - reviewList : MagazineTastingCommentResponseDto, + magazineList: ItemSnapshotList, + perfumeList: RecentPerfumeResponseDto, + reviewList: MagazineTastingCommentResponseDto, onNavPerfumeDesc: (Int) -> Unit, onNavCommunityDesc: (Int) -> Unit, onNavMagazineDesc: (Int) -> Unit -){ - if (magazineList.isNotEmpty()){ +) { + if (magazineList.isNotEmpty()) { val magazines = magazineList.subList(0, 5) LazyColumn( modifier = Modifier .fillMaxSize(), verticalArrangement = Arrangement.spacedBy(56.dp) - ){ - item{ + ) { + item { MagazineTitleBox( magazines = magazines.filterNotNull() ) @@ -145,8 +128,8 @@ private fun MagazineFullContent( MagazineHeader() Spacer(Modifier.height(24.dp)) } - items(magazineList){magazine -> - if (magazine != null){ + items(magazineList) { magazine -> + if (magazine != null) { MagazineContent( imageUrl = magazine.previewImgUrl, title = magazine.title, @@ -165,11 +148,11 @@ private fun MagazineFullContent( @Composable private fun MagazineTitleBox( magazines: List, -){ - val state = rememberPagerState(initialPage = 0, pageCount = {magazines.size}) +) { + val state = rememberPagerState(initialPage = 0, pageCount = { magazines.size }) HorizontalPager( state = state - ){ + ) { val imageUrl = magazines[it].previewImgUrl val title = magazines[it].title val preview = magazines[it].preview @@ -178,7 +161,7 @@ private fun MagazineTitleBox( .fillMaxWidth() .height(513.dp), contentAlignment = Alignment.Center - ){ + ) { ImageView( imageUrl = imageUrl, width = 1f, @@ -193,7 +176,7 @@ private fun MagazineTitleBox( .padding(horizontal = 16.dp) .padding(bottom = 22.dp) .background(color = Color.Transparent) - ){ + ) { TopBar( color = Color.Transparent, title = "Magazine", @@ -203,7 +186,7 @@ private fun MagazineTitleBox( modifier = Modifier .fillMaxSize() .aspectRatio(1f) - ){ + ) { ImageView( imageUrl = imageUrl, width = 1f, @@ -219,7 +202,7 @@ private fun MagazineTitleBox( .padding(horizontal = 24.dp), verticalArrangement = Arrangement.Bottom, horizontalAlignment = Alignment.CenterHorizontally - ){ + ) { Text( text = title, fontSize = 24.sp, @@ -243,14 +226,14 @@ private fun MagazineTitleBox( @Composable private fun ReleasePerfumeList( - perfumeList : RecentPerfumeResponseDto, + perfumeList: RecentPerfumeResponseDto?, onNavPerfumeDesc: (Int) -> Unit -){ +) { Column( modifier = Modifier .fillMaxWidth() .wrapContentHeight() - ){ + ) { Text( modifier = Modifier.padding(16.dp), text = "출시 향수", @@ -270,13 +253,13 @@ private fun ReleasePerfumeList( LazyRow( modifier = Modifier.padding(16.dp), horizontalArrangement = Arrangement.spacedBy(8.dp) - ){ - items(perfumeList){perfume -> + ) { + items(perfumeList ?: emptyList()) { perfume -> PerfumeDescItem( imageUrl = perfume.perfumeImgUrl, brandName = perfume.brandName, perfumeName = perfume.perfumeName, - releaseDate = perfume.relaseDate, + releaseDate = perfume.releaseDate, onNavPerfumeDesc = { onNavPerfumeDesc(perfume.perfumeId) } ) } @@ -286,10 +269,10 @@ private fun ReleasePerfumeList( @Composable private fun Top10Reviews( - reviews : MagazineTastingCommentResponseDto, + reviews: MagazineTastingCommentResponseDto, onNavCommunityDesc: (Int) -> Unit -){ - Column{ +) { + Column { Text( modifier = Modifier.padding(start = 16.dp), text = "TOP 10 시향기", @@ -309,8 +292,8 @@ private fun Top10Reviews( LazyRow( modifier = Modifier.padding(horizontal = 16.dp), horizontalArrangement = Arrangement.spacedBy(8.dp) - ){ - items(reviews){review -> + ) { + items(reviews) { review -> ReviewContent( title = review.title, profileImg = review.profileImg, @@ -324,13 +307,13 @@ private fun Top10Reviews( } @Composable -private fun MagazineHeader(){ +private fun MagazineHeader() { Column( modifier = Modifier .fillMaxWidth() .wrapContentHeight() .padding(start = 16.dp) - ){ + ) { Text( text = "HMOA\nNEWS / 매거진", fontSize = 20.sp, @@ -339,31 +322,32 @@ private fun MagazineHeader(){ ) Spacer(Modifier.height(12.dp)) Text( - text="향모아가 전하는 향수 트렌드 이슈", - fontSize=14.sp, + text = "향모아가 전하는 향수 트렌드 이슈", + fontSize = 14.sp, fontFamily = FontFamily(Font(R.font.pretendard_regular)), color = Color.Black ) } } + @Composable private fun MagazineContent( - imageUrl : String, - title : String, - preview : String, + imageUrl: String, + title: String, + preview: String, onNavMagazineDesc: () -> Unit -){ +) { Column( modifier = Modifier .fillMaxWidth() .clickable { onNavMagazineDesc() } .padding(horizontal = 16.dp) - ){ + ) { Box( modifier = Modifier .fillMaxWidth() .aspectRatio(1f) - ){ + ) { ImageView( imageUrl = imageUrl, width = 1f, @@ -391,20 +375,20 @@ private fun MagazineContent( @Composable private fun PerfumeDescItem( - imageUrl : String, - brandName : String, - perfumeName : String, - releaseDate : String, + imageUrl: String, + brandName: String, + perfumeName: String, + releaseDate: String?, onNavPerfumeDesc: () -> Unit -){ +) { Column( - modifier = Modifier.clickable{ + modifier = Modifier.clickable { onNavPerfumeDesc() } ) { Box( modifier = Modifier.size(155.dp) - ){ + ) { ImageView( imageUrl = imageUrl, width = 1f, @@ -429,7 +413,7 @@ private fun PerfumeDescItem( ) Spacer(Modifier.height(8.dp)) Text( - text = releaseDate, + text = releaseDate ?: "", fontSize = 10.sp, fontFamily = FontFamily(Font(R.font.pretendard_regular)), color = CustomColor.gray3 @@ -439,12 +423,12 @@ private fun PerfumeDescItem( @Composable private fun ReviewContent( - title : String, - profileImg : String, - nickname : String, - content : String, + title: String, + profileImg: String, + nickname: String, + content: String, onNavCommunityDesc: () -> Unit -){ +) { Column( modifier = Modifier .width(296.dp) @@ -456,7 +440,7 @@ private fun ReviewContent( } .padding(horizontal = 20.dp) .padding(bottom = 20.dp, top = 24.dp) - ){ + ) { Text( text = title, fontSize = 16.sp, @@ -469,7 +453,7 @@ private fun ReviewContent( Row( modifier = Modifier.wrapContentSize(), verticalAlignment = Alignment.CenterVertically - ){ + ) { CircleImageView( imgUrl = profileImg, width = 20, From 14962f1dc2ead0bbb7e8cb43ddae2cd3cfe8bdcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8B=E1=85=B5=E1=84=8B=E1=85=AD=E1=86=BC=E1=84=8B?= =?UTF-8?q?=E1=85=B5=E1=86=AB?= Date: Fri, 6 Dec 2024 16:17:41 +0900 Subject: [PATCH 46/93] =?UTF-8?q?Chore:=201.2.0=20=EB=B2=84=EC=A0=84?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20?= =?UTF-8?q?=ED=91=9C=EA=B8=B0=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4dad643ea..29b2b7a17 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -22,8 +22,8 @@ android { applicationId = "com.hmoa.app" minSdk = 26 targetSdk = 34 - versionCode = 31 - versionName = "1.1.4" + versionCode = 33 + versionName = "1.2.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" manifestPlaceholders["REDIRECTION_PATH"] = localProperties["REDIRECTION_PATH"] as String From 3eca334fd3ee3fe344dadff2169582af41f012fe Mon Sep 17 00:00:00 2001 From: Lee YongIn <67788699+LeeYongIn0517@users.noreply.github.com> Date: Fri, 6 Dec 2024 17:48:53 +0900 Subject: [PATCH 47/93] Hotfix/1.2.0 (#190) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Feat: 테두리 있는 TextField Custom * Resource: 배경 없는 check 이미지 파일 추가 * Rename: 파라미터 이름 변경 * Feat: notes 파라미터 타입 변경 * Feat: 주문서 작성 화면 추가 * Feat: 주문서 작성 화면 Navigation 추가 * Feat: iterator 누락 수정 * Design: padding value 수정 * Feat: 주소 추가 화면 추가 * Feat: 주소 추가 Navigation 추가 * Design: 버튼 padding 수정 * Chore: gson 의존성 추가 * Feat: note id 파라미터 추가 * Feat: note pick result 네비게이션 추가 * Rename: 파라미터 명 변경 * Feat: note pick result navigation 파라미터 추가 * Feat: 임의의 note id flow 추가 * Feat: note id class 추가 * Feat: getCart, postNoteOrder 함수 추가 * Feat: 주문 response dto 추가 * Feat: 멤버 주소 Dto 추가 * Feat: 멤버 정보 Dto 추가 * Feat: Note Pick Result 비즈니스 로직 추가 * Feat: note pick result 네비게이션 콜백 추가 * Feat: note pick result 네비게이션 콜백 추가 * Feat: ui state 분기 * Design: space 조절 * Feat: product ids 파라미터 추가 * Feat: order 화면 navigation추가 * Feat: 콜백 파라미터 변경 * Design: 가격 텍스트 , 추가 * Feat: 주문 비즈니스 로직 추가 * Feat: 서비스 알림 배너 삭제 * Feat: Error Ui State 에러 유무 확인 함수 추가 * Feat: 주소 추가 비즈니스 로직 추가 * Style: 코드 스타일 변경 * Feat: 주소, 주문 함수 추가 * Feat: 정보 받아오는 로직 생성 * Feat: 주소 추가 비즈니스 로직 추가 * Feat: default address dto 추가 * Feat: default order dto 추가 * Feat: 공통 함수 추가 * Rename: 함수 명 변경 * Feat: Response dto 수정 * Feat: Response dto 수정 * Feat: flow 수정 * Feat: 주문 response dto 생성 * Feat: post note order response dto 생성 * Fix: hbti 설문 이전 화살표 네비게이팅 수정 * Feat: hbti 설문 질문 데이터모델 및 속성추가 * Feat: SurveyOptionList 수정 - 복수 응답 가능 및 클릭콜백 인자 추가 * Feat: SurveyOptionList 답안 데이터모델 수정 및 삭제/추가 기능 수정 * Test: HbtiSurveyViewmodel Hbti답안 추가/삭제 상태변수 테스트 * Feat: hbti정답리스트 변수 추가 * Test: hbtiAnswerIds 초기화 및 수정 메서드 테스트 추가 * Feat: hbtiAnswerIds 상태변수 업데이트 메서드 수정 * Feat: SurveyOptionList 컴포넌트 인수 추가 및 내부 상태변수 추가 - 누르는 즉시 상태 및 UI 색상 변화를 주기 위해 내부에 상태변수 추가 * Feat: 읽기 전용 hbtiAnswerIdState 변수 추가 * Test: HbtiSurveyViewModelTest 테스트 메서드 수정 * Refactor: HbtiData 불필요한 속성 제거 * Test: hbti 설문 종료 후 요청데이터 배열 값 확인 테스트 * Fix: username 누락 추가 * Rename: HbtiSurveyViewModel 이름 오타 수정 * Fix: HbtiSurveyResultContent 인수 누락 수정 * Fix: SurveyOptionList 컴포넌트 수정에 의한 향수수량선택 기능 수정 * Test: NoteOrderQuantitiyPickViewmodel 향료 수량 선택과정 테스트 작성 * Chore: 브랜치 이름 변경 * Delete: 불필요한 의존성 제거 * Chore: 디버그 전용 빌드 명령어로 교체 * Delete: 불필요한 코드 삭제 * Comment: survey options list 컴포넌트 파라미터 변경에 따른 주석 처리 * Feat: WebView 컴포넌트 추가 * Chore: github action 타깃 브랜치 변경 * Chore: androidTest 라이브러리 추가 * Test: HbtiSurveyResultScreen 테스트 클래스 생성 * Feat: 뒤로가기 버튼 동작 누락 수정 * Chore: 중복 라이브러리 제거 및 hilt androidTest 추가 * Chore: hilt 라이브러리 버전 충돌 및 빌드 오류 수정 * Delete: ErrorLoading 상태에서 로딩화면 제거 * Refactor: UI 테스트에 용이한 형태로 변경 * Test: HbtiSurveyResultScreen 로딩화면 존재확인 테스트 * Refactor: 테스트에 적합한 형태로 수정 * Chore: test.espresso 버전 변경 * Test: HbtiSurveyScreen uiState별 화면 테스트 생성 * HotFix: 토큰 빈값 나오는 현상 수정 * Delete: sample app 모듈 잔여파일 삭제 * Revert "Feature/hbti [HotFix, Test] 토큰 플로우 오작동 현상 수정 및 UI 테스트 추가" * Fix: 로그아웃, 계정 삭제 작업 동기적으로 수정 * Fix: 코루틴 디스패처 수정 * HotFix: Retrofit 및 인터셉터 객체 스코프 변경 -싱글톤 생성에서 호출마다 생성되게끔 변경 * HotFix: 토큰 빈값 나오는 현상 수정 * Refactor: ErrorUiSetView 내부 상태변수 제거 * Reverse "Revert"Feature/hbti [HotFix, Test] 토큰 플로우 오작동 현상 수정 및 UI 테스트 추가"" * Fix: ErrorUiSetView 인자 누락 수정 * Test: 에러다디얼로그 렌더링 확인 * Test: 향료선택컴포넌트 테스트 추가 * Fix: 상위클래스 메소드 누락 수정 * Fix: 향료 카테고리 선택 기능 버그 수정 * Test: 향료선택 뷰모델 테스트 * Feat: NoteSelect 데이터클래스 프로퍼티 변겨 반영 * Test: setUp 누락 메소드 추가 * Refactor: HBTI 로딩화면 및 뷰모델 따로 생성 * Fix: 향료수량선택결과 업데이트 코드 누락 수정 * Test: 향료수량 선택 최종 값 확인 테스트 * Chore: CI 테스트 명령어 추가 * Refactor: ErrorHandling 비즈니스 로직 분리 * Test: 에러 처리 상태변수 테스트 추가 * Fix: 에러메세지 코드 값 불일치 수정 * Refactor: 에러처리 함수 적용 * Delete: 합의된 유스케이스 원칙에 위배되는 케이스 정리 * Delete * Feat: hbti 다음 질문 버튼 disabled 상태관리 추가 * Test: hbti 다음 질문 버튼 disabled 상태관리 관련 함수 테스트 * Design: hbti 설문 화면 패딩 수정 * Feat: 향료수량 선택 화면 다음 버튼 disabled 상태관리 추가 * Test: 향료수량 선택 화면 다음 버튼 disabled 상태값 테스트 * Delete: 필요없는 구문 삭제 * Design: 향모아 향수 로고 로딩 추가 * Design: 디자인 디테일부분 수정 * Feat: 설문 리스트 컴포넌트 복수/단수 답안 UI처리 속성 추가 * Fix: 인덱스 에러 튕김현상 원인 수정 * Refactor: 에러처리 함수 * Design: NotePickImage 디자인 변경 반영 * Hbti 결제 시스템 연결 (#151) * Feat: WebView 컴포넌트 추가 * Feat: 우편 번호 파라미터 타입 변경 (Int -> String) * Feat: 비즈니스 로직 로딩 오류 해결 * Design: focus 잡힐 시 placeholder 제거 * Feat: navigation 이벤트 추가 * Design: 글자 수 제한 및 keyboard option 설정 * Design: 글자 수 제한 및 keyboard option 설정 * Design: 테두리 색상 변경 가능하도록 수정 * Fix: Dto 불일치 수정 * Fix: 데이터를 받아오지 못하는 오류 수정 * Feat: order 화면으로부터 주문자 정보를 받아오도록 설정 * Feat: order 화면으로부터 주문자 정보를 받아오도록 설정 * Feat: Error 처리 코드 추가 * Chore: 개인정보처리방침 웹뷰 생성 link 추가 * Rename: navigation 이벤트 명 변경 * Feat: 고정 link build config로 변경 * Feat: 초기 데이터 설정 * Chore: 웹뷰 링크 local properties 설정 * Feat: navigation 파라미터 추가 * Feat: delete note 함수 추가 * Feat: map에서 flatMapLatest로 변경 * Style: 코드 스타일 변경 * Style: 코드 스타일 변경 * Feat: ui state 로직 변경 * Style: 코드 스타일 변경 * Style: 코드 스타일 변경 * Feat: 멤버 정보, 주문 정보 유무에 따른 상태 업데이트 로직 변경 * Feat: ui state 업데이트 로직 변경 * Feat: delete note 함수 추가 * Feat: delete note 함수 추가 삭제 * Feat: navigation 이벤트 변경 * Feat: navigation 이벤트 변경 * Feat: 사용자 정보 저장 여부 변수 추가 * Feat: 개인정보 처리방침 selectable 설정 * Feat: 전체 선택 여부에 따른 개별 선택 선택 여부 변경 로직 추가 * Feat: 파라미터 변경 * Design: 색상 변경 * Design: 간격 조절 * Design: 간격 조절 * Design: keyboard option 숫자 타입으로 변경 * Design: 색상 변경 * Feat: component 구성 변경 * Feat: component 파라미터 변경 * Feat: component 파라미터 변경 * Feat: navigation 이벤트 추가 * Feat: 웹뷰 띄우는 이벤트 파라미터 추가 * Style: 공백 제거 * Design: 가운데 정렬 * Design: 크기 조절 * Feat: navigation 이벤트 추가 * Feat: 개인정보 처리방침 web view 추가 * Ignore: import 문 정리 * Rename: navigation 이벤트 파라미터 명 변경 * Feat: Serializable 태그 추가 * Chore: boot pay 의존성 추가 * Chore: network access 권한 허용 * Feat: request dto 추가 * Feat: 결제 type enum class 추가 * Feat: bootpay service 추가 * Feat: bootpay repository 추가 * Feat: bootpay repository 구현체 추가 * Feat: bootpay datastore 추가 * Feat: bootpay datastore 추가 * Chore: core-model 의존성 추가 * Feat: bootpay service di * Feat: bootpay repository di * Feat: bootpay repository di * Feat: boot pay 결제 api 사용 * Feat: boot pay 결제 api 추가 * Feat: boot pay analytics 초기화 * Feat: null 값 처리 * Feat: 미사용 UI 삭제 * Feat: 미사용 UI 삭제 * Feat: web view type에 따른 url 분기 * Feat: 결제 버튼 활성화 조건 추가 * Feat: 파라미터 변경 * Feat: web view 띄우는 이벤트 추가 * Feat: toast 메시지 삭제 * Fix: navigation시 route 파라미터에 빈 공백이 들어가 발생하는 오류 수정 * Design: text 수정 * Test: UI Test 수정 * Chore: 취소, 환불, 반품 처리 방침 url 추가 * Comment: navigation stack logging 코드 추가 * Feat: boot pay 결제 수단 설정 안하는 것으로 수정 * Feat: Web view type enum class 추가 * Feat: boot pay 결제 후 response 처리 * Feat: boot pay 결제 response 데이터 모델 추가 * Feat: response dto 변경 * Feat: route에 따른 navigation pop up 이벤트 추가 * Chore: hbti local properties CI 설정 추가 * Design: 주문 내역, 취소/반품 내역, 이용 약관 UI 추가 * Design: 주문 내역 item UI 추가 * Design: 주문 내역 화면 UI 추가 * Design: 주문 내역 화면 UI 추가 * Design: 결제 note list 아이템 UI Component 추가 * Design: 환불 / 반품 신청 화면 UI 추가 * Comment: 주석 정리 * Rename: Component 명 변경 (history >> record) * Design: horizontal 정렬 End 옵션 추가 * Chore: 삭제할 local properties 목록 추가 * Design: 환불 반품 내역 확인 UI 추가 * Design: 결제 완료 화면 UI 추가 * Feat: order result 경로 추가 * Feat: order result 화면 navigation 추가 * Feat: order result 화면 navigation 추가 * Feat: navigation 이벤트 추가 * Feat: navigation 이벤트 추가 * Feat: 결제 완료 후 order result 화면으로 이동 * Feat: navigation 이벤트 추가 * Fix: index out of range 오류 수정 * Feat: 부트페이 결제 화면 close 함수 추가 * Fix: return 위치로 인한 로직 오류 수정 * Feat: kakao 1대1 채팅 이벤트 추가 * Design: 이용 약관 UI 제거 * Fix: 오타 수정 및 클래스 누락 매개변수 수정 * Feat: 배송 완료 후 설문조회 메서드 및 데이터 모델 추가 * Refactor: TagBadge 속성 정리 * Refactor: SpiceSelectScreen 삭제 후 PerfumeRecommdendations화면 컴포넌트화 * Fix: PerfumeRecommendation화면 뷰, 뷰모델 생성 * Refactor: ProgressBar 유틸리티 함수 통합 * Feat: TagBadge 스크롤러 생성 * Delete: 불필요 속성 제거 * Feature/hbti shj (#154) * Feat: WebView 컴포넌트 추가 * Feat: 우편 번호 파라미터 타입 변경 (Int -> String) * Feat: 비즈니스 로직 로딩 오류 해결 * Design: focus 잡힐 시 placeholder 제거 * Feat: navigation 이벤트 추가 * Design: 글자 수 제한 및 keyboard option 설정 * Design: 글자 수 제한 및 keyboard option 설정 * Design: 테두리 색상 변경 가능하도록 수정 * Fix: Dto 불일치 수정 * Fix: 데이터를 받아오지 못하는 오류 수정 * Feat: order 화면으로부터 주문자 정보를 받아오도록 설정 * Feat: order 화면으로부터 주문자 정보를 받아오도록 설정 * Feat: Error 처리 코드 추가 * Chore: 개인정보처리방침 웹뷰 생성 link 추가 * Rename: navigation 이벤트 명 변경 * Feat: 고정 link build config로 변경 * Feat: 초기 데이터 설정 * Chore: 웹뷰 링크 local properties 설정 * Feat: navigation 파라미터 추가 * Feat: delete note 함수 추가 * Feat: map에서 flatMapLatest로 변경 * Style: 코드 스타일 변경 * Style: 코드 스타일 변경 * Feat: ui state 로직 변경 * Style: 코드 스타일 변경 * Style: 코드 스타일 변경 * Feat: 멤버 정보, 주문 정보 유무에 따른 상태 업데이트 로직 변경 * Feat: ui state 업데이트 로직 변경 * Feat: delete note 함수 추가 * Feat: delete note 함수 추가 삭제 * Feat: navigation 이벤트 변경 * Feat: navigation 이벤트 변경 * Feat: 사용자 정보 저장 여부 변수 추가 * Feat: 개인정보 처리방침 selectable 설정 * Feat: 전체 선택 여부에 따른 개별 선택 선택 여부 변경 로직 추가 * Feat: 파라미터 변경 * Design: 색상 변경 * Design: 간격 조절 * Design: 간격 조절 * Design: keyboard option 숫자 타입으로 변경 * Design: 색상 변경 * Feat: component 구성 변경 * Feat: component 파라미터 변경 * Feat: component 파라미터 변경 * Feat: navigation 이벤트 추가 * Feat: 웹뷰 띄우는 이벤트 파라미터 추가 * Style: 공백 제거 * Design: 가운데 정렬 * Design: 크기 조절 * Feat: navigation 이벤트 추가 * Feat: 개인정보 처리방침 web view 추가 * Ignore: import 문 정리 * Rename: navigation 이벤트 파라미터 명 변경 * Feat: Serializable 태그 추가 * Chore: boot pay 의존성 추가 * Chore: network access 권한 허용 * Feat: request dto 추가 * Feat: 결제 type enum class 추가 * Feat: bootpay service 추가 * Feat: bootpay repository 추가 * Feat: bootpay repository 구현체 추가 * Feat: bootpay datastore 추가 * Feat: bootpay datastore 추가 * Chore: core-model 의존성 추가 * Feat: bootpay service di * Feat: bootpay repository di * Feat: bootpay repository di * Feat: boot pay 결제 api 사용 * Feat: boot pay 결제 api 추가 * Feat: boot pay analytics 초기화 * Feat: null 값 처리 * Feat: 미사용 UI 삭제 * Feat: 미사용 UI 삭제 * Feat: web view type에 따른 url 분기 * Feat: 결제 버튼 활성화 조건 추가 * Feat: 파라미터 변경 * Feat: web view 띄우는 이벤트 추가 * Feat: toast 메시지 삭제 * Fix: navigation시 route 파라미터에 빈 공백이 들어가 발생하는 오류 수정 * Design: text 수정 * Test: UI Test 수정 * Chore: 취소, 환불, 반품 처리 방침 url 추가 * Comment: navigation stack logging 코드 추가 * Feat: boot pay 결제 수단 설정 안하는 것으로 수정 * Feat: Web view type enum class 추가 * Feat: boot pay 결제 후 response 처리 * Feat: boot pay 결제 response 데이터 모델 추가 * Feat: response dto 변경 * Feat: route에 따른 navigation pop up 이벤트 추가 * Chore: hbti local properties CI 설정 추가 * Design: 주문 내역, 취소/반품 내역, 이용 약관 UI 추가 * Design: 주문 내역 item UI 추가 * Design: 주문 내역 화면 UI 추가 * Design: 주문 내역 화면 UI 추가 * Design: 결제 note list 아이템 UI Component 추가 * Design: 환불 / 반품 신청 화면 UI 추가 * Comment: 주석 정리 * Rename: Component 명 변경 (history >> record) * Design: horizontal 정렬 End 옵션 추가 * Chore: 삭제할 local properties 목록 추가 * Design: 환불 반품 내역 확인 UI 추가 * Design: 결제 완료 화면 UI 추가 * Feat: order result 경로 추가 * Feat: order result 화면 navigation 추가 * Feat: order result 화면 navigation 추가 * Feat: navigation 이벤트 추가 * Feat: navigation 이벤트 추가 * Feat: 결제 완료 후 order result 화면으로 이동 * Feat: navigation 이벤트 추가 * Fix: index out of range 오류 수정 * Feat: 부트페이 결제 화면 close 함수 추가 * Fix: return 위치로 인한 로직 오류 수정 * Feat: kakao 1대1 채팅 이벤트 추가 * Design: 이용 약관 UI 제거 * Feat: 주문 내역 get 메서드 추가 * Feat: 주문 상태 Enum Class 추가 * Feat: 주문 내역 response dto 추가 * Remove: 미사용 클래스 삭제 * Feat: 환불 api 추가 * Feat: 배송 상태 번역 함수 추가 * Fix: 파라미터 타입 변경 (String >> Note) * Feat: api response에 따른 파라미터 타입 변경 * Feat: 주문 내역, 환불 화면 navigation graph에 추가 * Feat: 주문 내역 화면 비즈니스 로직과 연결 * Feat: 환불 신청 화면 비즈니스 로직과 연결 * Feat: 환불 신청 화면 비즈니스 로직 추가 * Feat: 주문 내역 비즈니스 로직 추가 * Fix: 파라미터 변경에 따른 수정 (String >> Note) * Feat: 주문 내역, 환불 화면 route graph에 추가 * Feat: 주문 내역 navigation 이벤트 추가 * Feat: 주문 내역 navigation 이벤트 추가 * Fix: 파라미터 타입 변경 (Not Null >> Nullable) * Fix: filter not 동작 오류 수정 * Fix: 가격 계산 로직 변경 * Fix: 엘비스 연산 처리 추가 * Fix: 파라미터 matching 실수 수정 * Design: 여백 조정 * Rename: 파라미터 명 변경 * Feat: 환불 api 완료 후에 이전 화면으로 navigation 되도록 설정 * Feat: 가격 계산 관련 비즈니스 로직 수정 * Comment: Log 삭제 * Feat: Web Link 연결에서 Web View 사용으로 변경 * Remove: 미사용 UI 삭제 * Feat: postPerfumeSurvey 관련 data계층 생성 * Feat: HbtiNavgiation 화면 추가 * Fix: PerfumeSurveyScreen 및 Viewmodel 수정 * Rename: 복수 정답 여부 속성 이름 변경 * Feature/hbti shj (#155) * Feat: WebView 컴포넌트 추가 * Feat: 우편 번호 파라미터 타입 변경 (Int -> String) * Feat: 비즈니스 로직 로딩 오류 해결 * Design: focus 잡힐 시 placeholder 제거 * Feat: navigation 이벤트 추가 * Design: 글자 수 제한 및 keyboard option 설정 * Design: 글자 수 제한 및 keyboard option 설정 * Design: 테두리 색상 변경 가능하도록 수정 * Fix: Dto 불일치 수정 * Fix: 데이터를 받아오지 못하는 오류 수정 * Feat: order 화면으로부터 주문자 정보를 받아오도록 설정 * Feat: order 화면으로부터 주문자 정보를 받아오도록 설정 * Feat: Error 처리 코드 추가 * Chore: 개인정보처리방침 웹뷰 생성 link 추가 * Rename: navigation 이벤트 명 변경 * Feat: 고정 link build config로 변경 * Feat: 초기 데이터 설정 * Chore: 웹뷰 링크 local properties 설정 * Feat: navigation 파라미터 추가 * Feat: delete note 함수 추가 * Feat: map에서 flatMapLatest로 변경 * Style: 코드 스타일 변경 * Style: 코드 스타일 변경 * Feat: ui state 로직 변경 * Style: 코드 스타일 변경 * Style: 코드 스타일 변경 * Feat: 멤버 정보, 주문 정보 유무에 따른 상태 업데이트 로직 변경 * Feat: ui state 업데이트 로직 변경 * Feat: delete note 함수 추가 * Feat: delete note 함수 추가 삭제 * Feat: navigation 이벤트 변경 * Feat: navigation 이벤트 변경 * Feat: 사용자 정보 저장 여부 변수 추가 * Feat: 개인정보 처리방침 selectable 설정 * Feat: 전체 선택 여부에 따른 개별 선택 선택 여부 변경 로직 추가 * Feat: 파라미터 변경 * Design: 색상 변경 * Design: 간격 조절 * Design: 간격 조절 * Design: keyboard option 숫자 타입으로 변경 * Design: 색상 변경 * Feat: component 구성 변경 * Feat: component 파라미터 변경 * Feat: component 파라미터 변경 * Feat: navigation 이벤트 추가 * Feat: 웹뷰 띄우는 이벤트 파라미터 추가 * Style: 공백 제거 * Design: 가운데 정렬 * Design: 크기 조절 * Feat: navigation 이벤트 추가 * Feat: 개인정보 처리방침 web view 추가 * Ignore: import 문 정리 * Rename: navigation 이벤트 파라미터 명 변경 * Feat: Serializable 태그 추가 * Chore: boot pay 의존성 추가 * Chore: network access 권한 허용 * Feat: request dto 추가 * Feat: 결제 type enum class 추가 * Feat: bootpay service 추가 * Feat: bootpay repository 추가 * Feat: bootpay repository 구현체 추가 * Feat: bootpay datastore 추가 * Feat: bootpay datastore 추가 * Chore: core-model 의존성 추가 * Feat: bootpay service di * Feat: bootpay repository di * Feat: bootpay repository di * Feat: boot pay 결제 api 사용 * Feat: boot pay 결제 api 추가 * Feat: boot pay analytics 초기화 * Feat: null 값 처리 * Feat: 미사용 UI 삭제 * Feat: 미사용 UI 삭제 * Feat: web view type에 따른 url 분기 * Feat: 결제 버튼 활성화 조건 추가 * Feat: 파라미터 변경 * Feat: web view 띄우는 이벤트 추가 * Feat: toast 메시지 삭제 * Fix: navigation시 route 파라미터에 빈 공백이 들어가 발생하는 오류 수정 * Design: text 수정 * Test: UI Test 수정 * Chore: 취소, 환불, 반품 처리 방침 url 추가 * Comment: navigation stack logging 코드 추가 * Feat: boot pay 결제 수단 설정 안하는 것으로 수정 * Feat: Web view type enum class 추가 * Feat: boot pay 결제 후 response 처리 * Feat: boot pay 결제 response 데이터 모델 추가 * Feat: response dto 변경 * Feat: route에 따른 navigation pop up 이벤트 추가 * Chore: hbti local properties CI 설정 추가 * Design: 주문 내역, 취소/반품 내역, 이용 약관 UI 추가 * Design: 주문 내역 item UI 추가 * Design: 주문 내역 화면 UI 추가 * Design: 주문 내역 화면 UI 추가 * Design: 결제 note list 아이템 UI Component 추가 * Design: 환불 / 반품 신청 화면 UI 추가 * Comment: 주석 정리 * Rename: Component 명 변경 (history >> record) * Design: horizontal 정렬 End 옵션 추가 * Chore: 삭제할 local properties 목록 추가 * Design: 환불 반품 내역 확인 UI 추가 * Design: 결제 완료 화면 UI 추가 * Feat: order result 경로 추가 * Feat: order result 화면 navigation 추가 * Feat: order result 화면 navigation 추가 * Feat: navigation 이벤트 추가 * Feat: navigation 이벤트 추가 * Feat: 결제 완료 후 order result 화면으로 이동 * Feat: navigation 이벤트 추가 * Fix: index out of range 오류 수정 * Feat: 부트페이 결제 화면 close 함수 추가 * Fix: return 위치로 인한 로직 오류 수정 * Feat: kakao 1대1 채팅 이벤트 추가 * Design: 이용 약관 UI 제거 * Feat: 주문 내역 get 메서드 추가 * Feat: 주문 상태 Enum Class 추가 * Feat: 주문 내역 response dto 추가 * Remove: 미사용 클래스 삭제 * Feat: 환불 api 추가 * Feat: 배송 상태 번역 함수 추가 * Fix: 파라미터 타입 변경 (String >> Note) * Feat: api response에 따른 파라미터 타입 변경 * Feat: 주문 내역, 환불 화면 navigation graph에 추가 * Feat: 주문 내역 화면 비즈니스 로직과 연결 * Feat: 환불 신청 화면 비즈니스 로직과 연결 * Feat: 환불 신청 화면 비즈니스 로직 추가 * Feat: 주문 내역 비즈니스 로직 추가 * Fix: 파라미터 변경에 따른 수정 (String >> Note) * Feat: 주문 내역, 환불 화면 route graph에 추가 * Feat: 주문 내역 navigation 이벤트 추가 * Feat: 주문 내역 navigation 이벤트 추가 * Fix: 파라미터 타입 변경 (Not Null >> Nullable) * Fix: filter not 동작 오류 수정 * Fix: 가격 계산 로직 변경 * Fix: 엘비스 연산 처리 추가 * Fix: 파라미터 matching 실수 수정 * Design: 여백 조정 * Rename: 파라미터 명 변경 * Feat: 환불 api 완료 후에 이전 화면으로 navigation 되도록 설정 * Feat: 가격 계산 관련 비즈니스 로직 수정 * Comment: Log 삭제 * Feat: Web Link 연결에서 Web View 사용으로 변경 * Remove: 미사용 UI 삭제 * Feat: 파라미터 타입 변경 (not null >> nullable) * Feat: 파라미터 값 null 여부에 따른 UI 분기 * Rename: navigation route 클래스 위치 이동 (각 feature 모듈 >> core-domain.entity) * Rename: navigation route 클래스 위치 이동 (각 feature 모듈 >> core-domain.entity) * Rename: navigation 이벤트 명 변경 * Rename: navigation 이벤트 명 변경 * Rename: navigation 이벤트 명 변경 * Rename: entity 위치 변경 (각 feature 모듈 & core-model >> core-domain) * Feat: decode from string import 누락 추가 * Feat: decode from string import 누락 추가 * Feat: 주문 내역 조회 paging 처리 * Feat: nullable 처리 * Rename: 파라미터 명 변경 * Chore: 의존성 중복 제거 * Rename: 파라미터 이름 변경 * Fix: 파라미터 변경 * Rename: navigation 이벤트 명 변경 * Rename: 화면 명 변경 * Feat: 환불/반품 내역 조회 api 추가 * Rename: 함수 이름 변경 (getRefund >> getRefundRecord) * Rename: 함수 이름 변경 (getFavoriteCommentPaging >> getOrderRecordPaging) * Rename: 파일 명 변경 (ReturnOrRefundRecordPage >> RefundRecordPage) * Feat: 반품/환불 내역 비즈니스 로직 추가 * Feat: Empty Data Page 컴포넌트 추가 * Feat: view model 연결 * Feat: view model 추가 * Feat: view model 연결 * Fix: 패키지 명 다른 오류 수정 * Remove: 미사용 resource 삭제 * Rename: 디렉토리 명 변경 (Screen >> screen) * Feat: import 문 정리 * Rename: 패키지 명 변경 적용 * Rename: 패키지 명 변경 적용 * Design: padding 조절 * Fix: Response Dto 변경 * Feat: 환불 내역 조회 response 모델 추가 * Feat: response 변경에 따른 createAt 정보 추가 * Feat: navigation 이벤트 추가 * Feat: navigation 이벤트 추가 * Feat: order status 취소 완료 상태 추가 * Feat: order status 반품 완료 상태 추가 * Fix: UI 배송비 누락 수정 * Fix: UI 배송비 누락 수정 * Feat: 반품 완료 상태 추가 * Fix: 배송비 UI 누락 수정 * Design: UI 정렬 * Design: 버튼 삭제 * Remove: 미사용 화면 삭제 * Feat: NoDataPage >> EmptyDataPage 변경 * Fix: PerfumeRecommend 향료 선택 화면 수정 * Fix: 향료 태그 아이템 선택 및 삭제 동작 수정 * Test: 테스트이름 수정 및 오류 구문 수정 * Feature/hbti shj (#156) * Feat: WebView 컴포넌트 추가 * Feat: 우편 번호 파라미터 타입 변경 (Int -> String) * Feat: 비즈니스 로직 로딩 오류 해결 * Design: focus 잡힐 시 placeholder 제거 * Feat: navigation 이벤트 추가 * Design: 글자 수 제한 및 keyboard option 설정 * Design: 글자 수 제한 및 keyboard option 설정 * Design: 테두리 색상 변경 가능하도록 수정 * Fix: Dto 불일치 수정 * Fix: 데이터를 받아오지 못하는 오류 수정 * Feat: order 화면으로부터 주문자 정보를 받아오도록 설정 * Feat: order 화면으로부터 주문자 정보를 받아오도록 설정 * Feat: Error 처리 코드 추가 * Chore: 개인정보처리방침 웹뷰 생성 link 추가 * Rename: navigation 이벤트 명 변경 * Feat: 고정 link build config로 변경 * Feat: 초기 데이터 설정 * Chore: 웹뷰 링크 local properties 설정 * Feat: navigation 파라미터 추가 * Feat: delete note 함수 추가 * Feat: map에서 flatMapLatest로 변경 * Style: 코드 스타일 변경 * Style: 코드 스타일 변경 * Feat: ui state 로직 변경 * Style: 코드 스타일 변경 * Style: 코드 스타일 변경 * Feat: 멤버 정보, 주문 정보 유무에 따른 상태 업데이트 로직 변경 * Feat: ui state 업데이트 로직 변경 * Feat: delete note 함수 추가 * Feat: delete note 함수 추가 삭제 * Feat: navigation 이벤트 변경 * Feat: navigation 이벤트 변경 * Feat: 사용자 정보 저장 여부 변수 추가 * Feat: 개인정보 처리방침 selectable 설정 * Feat: 전체 선택 여부에 따른 개별 선택 선택 여부 변경 로직 추가 * Feat: 파라미터 변경 * Design: 색상 변경 * Design: 간격 조절 * Design: 간격 조절 * Design: keyboard option 숫자 타입으로 변경 * Design: 색상 변경 * Feat: component 구성 변경 * Feat: component 파라미터 변경 * Feat: component 파라미터 변경 * Feat: navigation 이벤트 추가 * Feat: 웹뷰 띄우는 이벤트 파라미터 추가 * Style: 공백 제거 * Design: 가운데 정렬 * Design: 크기 조절 * Feat: navigation 이벤트 추가 * Feat: 개인정보 처리방침 web view 추가 * Ignore: import 문 정리 * Rename: navigation 이벤트 파라미터 명 변경 * Feat: Serializable 태그 추가 * Chore: boot pay 의존성 추가 * Chore: network access 권한 허용 * Feat: request dto 추가 * Feat: 결제 type enum class 추가 * Feat: bootpay service 추가 * Feat: bootpay repository 추가 * Feat: bootpay repository 구현체 추가 * Feat: bootpay datastore 추가 * Feat: bootpay datastore 추가 * Chore: core-model 의존성 추가 * Feat: bootpay service di * Feat: bootpay repository di * Feat: bootpay repository di * Feat: boot pay 결제 api 사용 * Feat: boot pay 결제 api 추가 * Feat: boot pay analytics 초기화 * Feat: null 값 처리 * Feat: 미사용 UI 삭제 * Feat: 미사용 UI 삭제 * Feat: web view type에 따른 url 분기 * Feat: 결제 버튼 활성화 조건 추가 * Feat: 파라미터 변경 * Feat: web view 띄우는 이벤트 추가 * Feat: toast 메시지 삭제 * Fix: navigation시 route 파라미터에 빈 공백이 들어가 발생하는 오류 수정 * Design: text 수정 * Test: UI Test 수정 * Chore: 취소, 환불, 반품 처리 방침 url 추가 * Comment: navigation stack logging 코드 추가 * Feat: boot pay 결제 수단 설정 안하는 것으로 수정 * Feat: Web view type enum class 추가 * Feat: boot pay 결제 후 response 처리 * Feat: boot pay 결제 response 데이터 모델 추가 * Feat: response dto 변경 * Feat: route에 따른 navigation pop up 이벤트 추가 * Chore: hbti local properties CI 설정 추가 * Design: 주문 내역, 취소/반품 내역, 이용 약관 UI 추가 * Design: 주문 내역 item UI 추가 * Design: 주문 내역 화면 UI 추가 * Design: 주문 내역 화면 UI 추가 * Design: 결제 note list 아이템 UI Component 추가 * Design: 환불 / 반품 신청 화면 UI 추가 * Comment: 주석 정리 * Rename: Component 명 변경 (history >> record) * Design: horizontal 정렬 End 옵션 추가 * Chore: 삭제할 local properties 목록 추가 * Design: 환불 반품 내역 확인 UI 추가 * Design: 결제 완료 화면 UI 추가 * Feat: order result 경로 추가 * Feat: order result 화면 navigation 추가 * Feat: order result 화면 navigation 추가 * Feat: navigation 이벤트 추가 * Feat: navigation 이벤트 추가 * Feat: 결제 완료 후 order result 화면으로 이동 * Feat: navigation 이벤트 추가 * Fix: index out of range 오류 수정 * Feat: 부트페이 결제 화면 close 함수 추가 * Fix: return 위치로 인한 로직 오류 수정 * Feat: kakao 1대1 채팅 이벤트 추가 * Design: 이용 약관 UI 제거 * Feat: 주문 내역 get 메서드 추가 * Feat: 주문 상태 Enum Class 추가 * Feat: 주문 내역 response dto 추가 * Remove: 미사용 클래스 삭제 * Feat: 환불 api 추가 * Feat: 배송 상태 번역 함수 추가 * Fix: 파라미터 타입 변경 (String >> Note) * Feat: api response에 따른 파라미터 타입 변경 * Feat: 주문 내역, 환불 화면 navigation graph에 추가 * Feat: 주문 내역 화면 비즈니스 로직과 연결 * Feat: 환불 신청 화면 비즈니스 로직과 연결 * Feat: 환불 신청 화면 비즈니스 로직 추가 * Feat: 주문 내역 비즈니스 로직 추가 * Fix: 파라미터 변경에 따른 수정 (String >> Note) * Feat: 주문 내역, 환불 화면 route graph에 추가 * Feat: 주문 내역 navigation 이벤트 추가 * Feat: 주문 내역 navigation 이벤트 추가 * Fix: 파라미터 타입 변경 (Not Null >> Nullable) * Fix: filter not 동작 오류 수정 * Fix: 가격 계산 로직 변경 * Fix: 엘비스 연산 처리 추가 * Fix: 파라미터 matching 실수 수정 * Design: 여백 조정 * Rename: 파라미터 명 변경 * Feat: 환불 api 완료 후에 이전 화면으로 navigation 되도록 설정 * Feat: 가격 계산 관련 비즈니스 로직 수정 * Comment: Log 삭제 * Feat: Web Link 연결에서 Web View 사용으로 변경 * Remove: 미사용 UI 삭제 * Feat: 파라미터 타입 변경 (not null >> nullable) * Feat: 파라미터 값 null 여부에 따른 UI 분기 * Rename: navigation route 클래스 위치 이동 (각 feature 모듈 >> core-domain.entity) * Rename: navigation route 클래스 위치 이동 (각 feature 모듈 >> core-domain.entity) * Rename: navigation 이벤트 명 변경 * Rename: navigation 이벤트 명 변경 * Rename: navigation 이벤트 명 변경 * Rename: entity 위치 변경 (각 feature 모듈 & core-model >> core-domain) * Feat: decode from string import 누락 추가 * Feat: decode from string import 누락 추가 * Feat: 주문 내역 조회 paging 처리 * Feat: nullable 처리 * Rename: 파라미터 명 변경 * Chore: 의존성 중복 제거 * Rename: 파라미터 이름 변경 * Fix: 파라미터 변경 * Rename: navigation 이벤트 명 변경 * Rename: 화면 명 변경 * Feat: 환불/반품 내역 조회 api 추가 * Rename: 함수 이름 변경 (getRefund >> getRefundRecord) * Rename: 함수 이름 변경 (getFavoriteCommentPaging >> getOrderRecordPaging) * Rename: 파일 명 변경 (ReturnOrRefundRecordPage >> RefundRecordPage) * Feat: 반품/환불 내역 비즈니스 로직 추가 * Feat: Empty Data Page 컴포넌트 추가 * Feat: view model 연결 * Feat: view model 추가 * Feat: view model 연결 * Fix: 패키지 명 다른 오류 수정 * Remove: 미사용 resource 삭제 * Rename: 디렉토리 명 변경 (Screen >> screen) * Feat: import 문 정리 * Rename: 패키지 명 변경 적용 * Rename: 패키지 명 변경 적용 * Design: padding 조절 * Fix: Response Dto 변경 * Feat: 환불 내역 조회 response 모델 추가 * Feat: response 변경에 따른 createAt 정보 추가 * Feat: navigation 이벤트 추가 * Feat: navigation 이벤트 추가 * Feat: order status 취소 완료 상태 추가 * Feat: order status 반품 완료 상태 추가 * Fix: UI 배송비 누락 수정 * Fix: UI 배송비 누락 수정 * Feat: 반품 완료 상태 추가 * Fix: 배송비 UI 누락 수정 * Design: UI 정렬 * Design: 버튼 삭제 * Remove: 미사용 화면 삭제 * Feat: NoDataPage >> EmptyDataPage 변경 * Design: font 적용 * Remove: 미사용 import 문 제거 * Rename: 파라미터 명 변경 * Feat: 반품 진행 중 상태 추가 * Feat: order status를 기준으로 Button UI 분기 * Feat: 반품 진행 중 상태 추가 * Feat: 리뷰 작성 navigation 이벤트 추가 * Comment: 임의 이벤트 주석 추가 * Rename: 파일 위치 이동 (like 모듈 >> userInfo 모듈) * Rename: navigation 이벤트 명 변경 * Feat: 좋아요 한 향수 화면 route 추가 * Feat: navigation 이벤트 추가 * Remove: like 모듈 삭제 및 user info 모듈 병합 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Ignore: git pull * Feat: 향료추천 결과 캐시저장소 및 데이터 계층 메소드 생성 * Refactor: core-database 객체주입 모듈 위치 수정 * Feat: 향료 추천 화면 및 결과 화면 수정 * Feat: 최종 향료 설문 결과 제출로직 수정 * Test: 향료 설문 결과 매핑함수 테스트 * Fix: 오타 수정 * Fix: 향료 추천 결과 화면 튕김현상 수정 * Fix: 중복 코드 삭제 * Fix: 컴포넌트 및 매개변수 수정 반영 * Delete: 필요없는 속성 * Fix: 매개변수 이름 및 타입 변경 * Feat: 향수추천 결과 캐시 추가 * Design: 패딩 및 글자 위치 수정 * Design: 디자인 오류 삭제(그림자) * Feat: 향료추천 결과화면 완성 * Fix: 매개변수 변경 반영 * HotFix: 카카오 sdk 버전 업그레이드 * Release 1.1.2 버전 업로드 - 커밋 누락된 부분 추가 푸시 (#169) * Ignore * Ignore * Feat: feature-hbti 모듈 생성 * Feat:선택지 무효화 기능 추가 및 SurveyOptionList로 수정 * Rename: SurveyOptionItem -> SurveyOptionList * Feat: ProgressBarPreview에 +/- 효과 추가 * Chore: gradle 의존성 추가 * Fix: intent 이름 변경 * Feat: 알림 선택 시 읽음 처리 이벤트 추가 * Feat: 포그라운드 알림 처리 * Fix: Navigation Deeplink 오류 수정 * Chore: mockito 라이브러리 추가 * Feat: HbtiScreen 추가 * Chore: compose material 및 preview 라이브러리 추가 * Feat: Hbti화면 완성 * Design: 향BTI 화면 디자인 구성 완료 * Feat: 향BTI 테스트 데이터계층 클래스 생성 * Rename: SurveyAnswerResponseDto -> SurveyOptionResponseDto * Feat: fcm token 저장 함수 추가 * Fix: 파라미터 이름 오류 수정 * Fix: 토큰 저장 알고리즘 수정 * Feat: 향수 추천 화면 추가 * Design: 공백 수정 * Feat: 데이터 계층 hilt 주입코드 추가 * Feat: HbtiSurvey 화면 추가(미완성) * Feat: 가격 선택 화면 추가 * Design: 아이템 간 간격 조절 * Rename: 컴포넌트 이름 변경 * Rename: 컴포넌트 이름 변경 * Feat: 향료 선택 화면 추가 * Refactor: 화면 구성 변경 * Fix: 파라미터 변경 * Resource: icon 추가 * Fix: 파라미터 수정 * Feat: 향료 선택 화면 추가 * Style: 공백 스타일 변경 * Fix: 푸쉬 오류 수정 * Style: 코드 스타일 변경 * Feat: 향수 추천 결과 화면 추가 * Rename: 컴포넌트 이름 변경 * Ignore * Delete * Chore: test 라이브러리 추가 * Feat: HbtiSurveyViewmodel 생성 * Test: HbtiSurveyViewModel 테스트 생성 * Test: 테스트 기대값 수정 * Feat: Dto 추가 * Feat: Api 추가 * Style: 코드 라인 변경 * Feat: 비즈니스 로직 추가 * Remove: 삭제 * Feat: 향료 데이터 클래스 추가 * Comment: 주석 추가 * Fix: 서버에 정보 전달 로직 임의 대체 * Rename: 함수 명 변경 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: UI 상태 기준 분기 * Feat: Navigation 설정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Chore: core-common 의존성 추가 * Delete: 토큰 재발급 임시 로직 삭제 * HotFix: Authenticator 토큰 재발급 및 에러메세지 전달 기능 수정 * Fix: Authenticator 적용 * Fix: api 호출부에 Authenticator 적용 * Delete: 안쓰는 api 삭제 * Refactor: FCM 초기화 및 초기 라우팅 코드 함수로 분리 * Delete: 임시 refreshToken 코드 관련 api 삭제 * Rename: 토큰 관련 클래스 의존성 주입 모듈 이름 수정 * Fix: 토큰 동적 할당 시점 변경 * Fix: 로그인 화면 이동 네비게이션 변경 * Chore: 버전 변경 (v1.1.1 -> v1.1.2) * Chore: ci,cd 구문 변경 및 action.yml 파일 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: ci/cd 워크플로우 임시로 주석처리 및 사용중지 * Chore: android.yml 워크플로우 일시중지 (#164) * Chore: CI 구문 롤백 및 오작동 CI/CD 임시폴더로 분리 * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 * Fix: 파라미터 명시적으로 구분 * Fix: RouteScreen 파라미터 변수명 변경 반영 * Chore: 버전코드 수정 22->23 * Ignore * Fix: 백업데이터 설정 해제 * Chore: 버전 업데이트 * Revert "Chore: 버전 업데이트" This reverts commit 031fc2f141d3ffbc07b0954eda874c58d7e1c834. * Revert "Fix: 백업데이터 설정 해제" This reverts commit bb68a8d265be89d74bcc2feed66baca5355cd475. * 1.1.2버전 develop -> release 머지합니다 (#168) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Chore: core-common 의존성 추가 * Delete: 토큰 재발급 임시 로직 삭제 * HotFix: Authenticator 토큰 재발급 및 에러메세지 전달 기능 수정 * Fix: Authenticator 적용 * Fix: api 호출부에 Authenticator 적용 * Delete: 안쓰는 api 삭제 * Refactor: FCM 초기화 및 초기 라우팅 코드 함수로 분리 * Delete: 임시 refreshToken 코드 관련 api 삭제 * Rename: 토큰 관련 클래스 의존성 주입 모듈 이름 수정 * Fix: 토큰 동적 할당 시점 변경 * Fix: 로그인 화면 이동 네비게이션 변경 * Chore: 버전 변경 (v1.1.1 -> v1.1.2) * Chore: ci,cd 구문 변경 및 action.yml 파일 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 * Chore: ci/cd 워크플로우 임시로 주석처리 및 사용중지 * Chore: CI 구문 롤백 및 오작동 CI/CD 임시폴더로 분리 * Fix: 파라미터 명시적으로 구분 * Fix: RouteScreen 파라미터 변수명 변경 반영 * Chore: 버전코드 수정 22->23 * Ignore * Fix: 백업데이터 설정 해제 * Chore: 버전 업데이트 * Revert "Chore: 버전 업데이트" This reverts commit 031fc2f141d3ffbc07b0954eda874c58d7e1c834. * Revert "Fix: 백업데이터 설정 해제" This reverts commit bb68a8d265be89d74bcc2feed66baca5355cd475. --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Delete * Delete * Delete --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * HotFix: 카카오 sdk 버전 업그레이드 (#170) * HotFix: 카카오 sdk 버전 업그레이드 * Feat: gradlew clean 작업 추가 * Delete * Delete: refreshToken 추상메서드 삭제 * Delete: 토큰 리프레싱 임시방안 코드 삭제 * HotFix: 카카오 sdk 버전 업그레이드 (#174) * v1.1.3 업데이트 (#172) * Ignore * Feat: feature-hbti 모듈 생성 * Feat:선택지 무효화 기능 추가 및 SurveyOptionList로 수정 * Rename: SurveyOptionItem -> SurveyOptionList * Feat: ProgressBarPreview에 +/- 효과 추가 * Chore: gradle 의존성 추가 * Fix: intent 이름 변경 * Feat: 알림 선택 시 읽음 처리 이벤트 추가 * Feat: 포그라운드 알림 처리 * Fix: Navigation Deeplink 오류 수정 * Chore: mockito 라이브러리 추가 * Feat: HbtiScreen 추가 * Chore: compose material 및 preview 라이브러리 추가 * Feat: Hbti화면 완성 * Design: 향BTI 화면 디자인 구성 완료 * Feat: 향BTI 테스트 데이터계층 클래스 생성 * Rename: SurveyAnswerResponseDto -> SurveyOptionResponseDto * Feat: fcm token 저장 함수 추가 * Fix: 파라미터 이름 오류 수정 * Fix: 토큰 저장 알고리즘 수정 * Feat: 향수 추천 화면 추가 * Design: 공백 수정 * Feat: 데이터 계층 hilt 주입코드 추가 * Feat: HbtiSurvey 화면 추가(미완성) * Feat: 가격 선택 화면 추가 * Design: 아이템 간 간격 조절 * Rename: 컴포넌트 이름 변경 * Rename: 컴포넌트 이름 변경 * Feat: 향료 선택 화면 추가 * Refactor: 화면 구성 변경 * Fix: 파라미터 변경 * Resource: icon 추가 * Fix: 파라미터 수정 * Feat: 향료 선택 화면 추가 * Style: 공백 스타일 변경 * Fix: 푸쉬 오류 수정 * Style: 코드 스타일 변경 * Feat: 향수 추천 결과 화면 추가 * Rename: 컴포넌트 이름 변경 * Ignore * Delete * Chore: test 라이브러리 추가 * Feat: HbtiSurveyViewmodel 생성 * Test: HbtiSurveyViewModel 테스트 생성 * Test: 테스트 기대값 수정 * Feat: Dto 추가 * Feat: Api 추가 * Style: 코드 라인 변경 * Feat: 비즈니스 로직 추가 * Remove: 삭제 * Feat: 향료 데이터 클래스 추가 * Comment: 주석 추가 * Fix: 서버에 정보 전달 로직 임의 대체 * Rename: 함수 명 변경 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: UI 상태 기준 분기 * Feat: Navigation 설정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Chore: core-common 의존성 추가 * Delete: 토큰 재발급 임시 로직 삭제 * HotFix: Authenticator 토큰 재발급 및 에러메세지 전달 기능 수정 * Fix: Authenticator 적용 * Fix: api 호출부에 Authenticator 적용 * Delete: 안쓰는 api 삭제 * Refactor: FCM 초기화 및 초기 라우팅 코드 함수로 분리 * Delete: 임시 refreshToken 코드 관련 api 삭제 * Rename: 토큰 관련 클래스 의존성 주입 모듈 이름 수정 * Fix: 토큰 동적 할당 시점 변경 * Fix: 로그인 화면 이동 네비게이션 변경 * Chore: 버전 변경 (v1.1.1 -> v1.1.2) * Chore: ci,cd 구문 변경 및 action.yml 파일 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: ci/cd 워크플로우 임시로 주석처리 및 사용중지 * Chore: android.yml 워크플로우 일시중지 (#164) * Chore: CI 구문 롤백 및 오작동 CI/CD 임시폴더로 분리 * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 * Fix: 파라미터 명시적으로 구분 * Fix: RouteScreen 파라미터 변수명 변경 반영 * Chore: 버전코드 수정 22->23 * Ignore * Fix: 백업데이터 설정 해제 * Chore: 버전 업데이트 * Revert "Chore: 버전 업데이트" This reverts commit 031fc2f141d3ffbc07b0954eda874c58d7e1c834. * Revert "Fix: 백업데이터 설정 해제" This reverts commit bb68a8d265be89d74bcc2feed66baca5355cd475. * 1.1.2버전 develop -> release 머지합니다 (#168) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Chore: core-common 의존성 추가 * Delete: 토큰 재발급 임시 로직 삭제 * HotFix: Authenticator 토큰 재발급 및 에러메세지 전달 기능 수정 * Fix: Authenticator 적용 * Fix: api 호출부에 Authenticator 적용 * Delete: 안쓰는 api 삭제 * Refactor: FCM 초기화 및 초기 라우팅 코드 함수로 분리 * Delete: 임시 refreshToken 코드 관련 api 삭제 * Rename: 토큰 관련 클래스 의존성 주입 모듈 이름 수정 * Fix: 토큰 동적 할당 시점 변경 * Fix: 로그인 화면 이동 네비게이션 변경 * Chore: 버전 변경 (v1.1.1 -> v1.1.2) * Chore: ci,cd 구문 변경 및 action.yml 파일 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 * Chore: ci/cd 워크플로우 임시로 주석처리 및 사용중지 * Chore: CI 구문 롤백 및 오작동 CI/CD 임시폴더로 분리 * Fix: 파라미터 명시적으로 구분 * Fix: RouteScreen 파라미터 변수명 변경 반영 * Chore: 버전코드 수정 22->23 * Ignore * Fix: 백업데이터 설정 해제 * Chore: 버전 업데이트 * Revert "Chore: 버전 업데이트" This reverts commit 031fc2f141d3ffbc07b0954eda874c58d7e1c834. * Revert "Fix: 백업데이터 설정 해제" This reverts commit bb68a8d265be89d74bcc2feed66baca5355cd475. --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Delete * Delete * Delete * HotFix: 카카오 sdk 버전 업그레이드 (#170) (#171) * HotFix: 카카오 sdk 버전 업그레이드 * Feat: gradlew clean 작업 추가 * Delete * Delete: refreshToken 추상메서드 삭제 * Delete: 토큰 리프레싱 임시방안 코드 삭제 * v1.1.3 업데이트 수정 (#175) * HotFix: 카카오 sdk 버전 업그레이드 (#170) * HotFix: 카카오 sdk 버전 업그레이드 * Feat: gradlew clean 작업 추가 * Delete * Delete: refreshToken 추상메서드 삭제 * Delete: 토큰 리프레싱 임시방안 코드 삭제 * HotFix: 카카오 sdk 버전 업그레이드 (#174) --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> Co-authored-by: uselessNaming * Hotfix/community (#176) * Fix: 좋아요 반영 안되는 오류 수정 * Fix: response에 wrapping 추가 * Design: 내용 및 사진 누락 추가 * Fix: response wrapping * Design: 디자인 누락 추가 * Refactor: 불필요 로직 삭제 * Feat: 파라미터 명 변경 * Design: 버튼 가려지는 현상 수정 * Fix: hbti 향료개수 자유선택 후 튕기는 현상 수정 * Fix: hbti 향료 선택결과 제출로직 변경 * Fix: hbti 향료선택화면 하단버튼 disabled 상태관리 추가 * Fix: hbti 향료 카테고리 선택화면 로직 변경 반영 * Test: hbti 향료 카테고리 선택화면 로직 변경사항 테스트 * Design: 백버튼 추가 * Feat: 향료 제품 가격 추가 * Refactor: 플래그 제거 및 콜백으로 대체 * Feature/hbti shj (#177) * Comment: navigation stack logging 코드 추가 * Feat: boot pay 결제 수단 설정 안하는 것으로 수정 * Feat: Web view type enum class 추가 * Feat: boot pay 결제 후 response 처리 * Feat: boot pay 결제 response 데이터 모델 추가 * Feat: response dto 변경 * Feat: route에 따른 navigation pop up 이벤트 추가 * Chore: hbti local properties CI 설정 추가 * Design: 주문 내역, 취소/반품 내역, 이용 약관 UI 추가 * Design: 주문 내역 item UI 추가 * Design: 주문 내역 화면 UI 추가 * Design: 주문 내역 화면 UI 추가 * Design: 결제 note list 아이템 UI Component 추가 * Design: 환불 / 반품 신청 화면 UI 추가 * Comment: 주석 정리 * Rename: Component 명 변경 (history >> record) * Design: horizontal 정렬 End 옵션 추가 * Chore: 삭제할 local properties 목록 추가 * Design: 환불 반품 내역 확인 UI 추가 * Design: 결제 완료 화면 UI 추가 * Feat: order result 경로 추가 * Feat: order result 화면 navigation 추가 * Feat: order result 화면 navigation 추가 * Feat: navigation 이벤트 추가 * Feat: navigation 이벤트 추가 * Feat: 결제 완료 후 order result 화면으로 이동 * Feat: navigation 이벤트 추가 * Fix: index out of range 오류 수정 * Feat: 부트페이 결제 화면 close 함수 추가 * Fix: return 위치로 인한 로직 오류 수정 * Feat: kakao 1대1 채팅 이벤트 추가 * Design: 이용 약관 UI 제거 * Feat: 주문 내역 get 메서드 추가 * Feat: 주문 상태 Enum Class 추가 * Feat: 주문 내역 response dto 추가 * Remove: 미사용 클래스 삭제 * Feat: 환불 api 추가 * Feat: 배송 상태 번역 함수 추가 * Fix: 파라미터 타입 변경 (String >> Note) * Feat: api response에 따른 파라미터 타입 변경 * Feat: 주문 내역, 환불 화면 navigation graph에 추가 * Feat: 주문 내역 화면 비즈니스 로직과 연결 * Feat: 환불 신청 화면 비즈니스 로직과 연결 * Feat: 환불 신청 화면 비즈니스 로직 추가 * Feat: 주문 내역 비즈니스 로직 추가 * Fix: 파라미터 변경에 따른 수정 (String >> Note) * Feat: 주문 내역, 환불 화면 route graph에 추가 * Feat: 주문 내역 navigation 이벤트 추가 * Feat: 주문 내역 navigation 이벤트 추가 * Fix: 파라미터 타입 변경 (Not Null >> Nullable) * Fix: filter not 동작 오류 수정 * Fix: 가격 계산 로직 변경 * Fix: 엘비스 연산 처리 추가 * Fix: 파라미터 matching 실수 수정 * Design: 여백 조정 * Rename: 파라미터 명 변경 * Feat: 환불 api 완료 후에 이전 화면으로 navigation 되도록 설정 * Feat: 가격 계산 관련 비즈니스 로직 수정 * Comment: Log 삭제 * Feat: Web Link 연결에서 Web View 사용으로 변경 * Remove: 미사용 UI 삭제 * Feat: 파라미터 타입 변경 (not null >> nullable) * Feat: 파라미터 값 null 여부에 따른 UI 분기 * Rename: navigation route 클래스 위치 이동 (각 feature 모듈 >> core-domain.entity) * Rename: navigation route 클래스 위치 이동 (각 feature 모듈 >> core-domain.entity) * Rename: navigation 이벤트 명 변경 * Rename: navigation 이벤트 명 변경 * Rename: navigation 이벤트 명 변경 * Rename: entity 위치 변경 (각 feature 모듈 & core-model >> core-domain) * Feat: decode from string import 누락 추가 * Feat: decode from string import 누락 추가 * Feat: 주문 내역 조회 paging 처리 * Feat: nullable 처리 * Rename: 파라미터 명 변경 * Chore: 의존성 중복 제거 * Rename: 파라미터 이름 변경 * Fix: 파라미터 변경 * Rename: navigation 이벤트 명 변경 * Rename: 화면 명 변경 * Feat: 환불/반품 내역 조회 api 추가 * Rename: 함수 이름 변경 (getRefund >> getRefundRecord) * Rename: 함수 이름 변경 (getFavoriteCommentPaging >> getOrderRecordPaging) * Rename: 파일 명 변경 (ReturnOrRefundRecordPage >> RefundRecordPage) * Feat: 반품/환불 내역 비즈니스 로직 추가 * Feat: Empty Data Page 컴포넌트 추가 * Feat: view model 연결 * Feat: view model 추가 * Feat: view model 연결 * Fix: 패키지 명 다른 오류 수정 * Remove: 미사용 resource 삭제 * Rename: 디렉토리 명 변경 (Screen >> screen) * Feat: import 문 정리 * Rename: 패키지 명 변경 적용 * Rename: 패키지 명 변경 적용 * Design: padding 조절 * Fix: Response Dto 변경 * Feat: 환불 내역 조회 response 모델 추가 * Feat: response 변경에 따른 createAt 정보 추가 * Feat: navigation 이벤트 추가 * Feat: navigation 이벤트 추가 * Feat: order status 취소 완료 상태 추가 * Feat: order status 반품 완료 상태 추가 * Fix: UI 배송비 누락 수정 * Fix: UI 배송비 누락 수정 * Feat: 반품 완료 상태 추가 * Fix: 배송비 UI 누락 수정 * Design: UI 정렬 * Design: 버튼 삭제 * Remove: 미사용 화면 삭제 * Feat: NoDataPage >> EmptyDataPage 변경 * Design: font 적용 * Remove: 미사용 import 문 제거 * Rename: 파라미터 명 변경 * Feat: 반품 진행 중 상태 추가 * Feat: order status를 기준으로 Button UI 분기 * Feat: 반품 진행 중 상태 추가 * Feat: 리뷰 작성 navigation 이벤트 추가 * Comment: 임의 이벤트 주석 추가 * Rename: 파일 위치 이동 (like 모듈 >> userInfo 모듈) * Rename: navigation 이벤트 명 변경 * Feat: 좋아요 한 향수 화면 route 추가 * Feat: navigation 이벤트 추가 * Remove: like 모듈 삭제 및 user info 모듈 병합 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Ignore: git pull * Test: sort 로직 test * Feat: Paging 내 sort 추가 * Remove: 미사용 resource 삭제 * Fix: 카테고리 내용 변경 (시향기 >> 향BTI 시향기) * Refactor: 변수 위치 변경 * Revert * Ignore: git pull * Ignore: git pull * Feat: 리뷰 컴포넌트 추가 * Feat: 선택 시 사진 확대 추가 * Feat: 선택 시 사진 확대 추가 * Design: 색상 반전 여부 추가 * Feat: int RequestBody형으로 변환 함수 추가 * Chore: decode string 함수 의존성 추가 * Feat: 리뷰 관련 dto 추가 * Feat: photo dto 추가 * Feat: h shop review 관련 api 추가 * Feat: h shop review 관련 api 추가 * Feat: 좋아요 개수 파라미터 추가 * Design: 반전 여부 추가 * Feat: review 화면 추가 * Feat: path 변환 함수 (local uri >> absolute path) * Feat: get my orders api 추가 * Feat: get my orders dto 추가 * Feat: 리뷰 작성 view model 추가 * Feat: 리뷰 작성 화면 view model 연결 * Chore: json decode import 추가 * Feat: 리뷰 작성 navigation 추가 * Fix: FAB 버튼 파라미터 변경 (고정 값 >> 변동 값) * Rename: my orders api 위치 변경 (HShop >> HShopReview) * Feat: 파라미터 타입 변경 (() -> Unit >> Unit) * Feat: navigation 이벤트 추가 * Chore: paging 의존성 추가 * Fix: val >> var * Feat: 선택 가능 여부 설정 파라미터 추가 * Feat: paging 클래스 추가 * Feat: 리뷰 화면 view model 추가 * Feat: 리뷰 화면 view model 연결 * Feat: HBTI 홈 view model 추가 * Design: 테두리 색상 남는 UI 수정 * Design: navigation icon 색상 값 추가 * Style: 코드 스타일 변경 * Feat: navigation 이벤트 추가 * Design: 디자인 파라미터 변경 * Design: 글 색 변경 * Feat: 리뷰 UI 추가 * Design: FAB 디자인 변경 * Design: FAB padding 변경 * Design: icon 색상 변경 * Design: FAB 디자인 변경 * Design: text 변경 * Design: TopBar 색상 변경 * Design: FAB 선택 시 배경 애니메이션 추가 * Design: 컴포넌트 색상 명시 * Feat: 성능 개선을 위한 분리 * Fix: public >> private * Feat: 신고, 삭제 이름 선언 * Feat: 삭제, 신고 이벤트 추가 * Fix: ui 성능 개선 * Remove: 불필요 변수 제거 * Remove: 불필요 변수 제거 * Fix: var >> val * Fix: 좋아요 로직 변경 * Feat: navigation 이벤트 추가 * Chore: material 의존성 추가 * Feat: 좋아요 이벤트 추가 * Feat: 좋아요, 삭제, 신고 기능 추가 * Feat: 수정 api 추가 * Feat: 리뷰 수정 화면 추가 * Feat: 리뷰 수정 비즈니스 로직 추가 * Feat: 리뷰 수정 화면 네비게이션 연결 * Ignore * Design: FAB 버튼 테두리 삭제 * Fix: navigation 이벤트 호출 수정 * Feat: 리뷰 단건 조회, 삭제 api 추가 * Feat: FAB option 변수 값 변경 * Feat: delete review 함수 연결 * Fix: part 어노테이션 네이밍 오류 수정 * Fix: 함수 파라미터 변경 * Fix: 함수 파라미터 변경 * Feat: 삭제 후 ui 반영되도록 flag 추가 * Fix: delay 시간 축소 * Remove: log 삭제 * Design: 아이콘 변경 * Design: 스크롤 범위 전체로 변경 * Feat: 개별 navigation 람다 적용 * Feat: 개별 navigation 람다 적용 * Fix: Part 어노테이션 이름 추가 * Feat: 리뷰 수정 화면 navigation 연결 * Feat: single top 옵션 추가 * Design: 배경 이미지 추가 * Feat: 신고 기능 추가 * Feat: 리뷰 신고 api 추가 * Fix: 파라미터 명 변경 * Style: 코드 줄 변경 * Feat: 이벤트 후 dialog 닫기 * Feat: 작성한 리뷰 navigation 연결 * Rename: getMyOrders api 위치 이동 (hShopReview >> HShop) * Feat: 내가 작성한 review api 추가 * Feat: 내가 작성한 review 화면 추가 * Feat: 내가 작성한 review view model 추가 * Feat: 내 review paging source * Feat: 내 review 화면 연결 * Rename: paging source 위치 이동 * Feat: 리뷰 완료 상태 추가 * Feat: navigation 이벤트 추가 * Feat: createdAt 멤버 변수 추가 * Design: 클릭 범위 변경 * Design: 클릭 범위 변경 * Feat: navigation 파라미터 추가 * Feat: 환불 버튼 클릭 시 dialog 생성 * Design: fontSize, lineHeight 조정 * Design: 날짜 추가, 색상 변경 * Remove: 미사용 dto 삭제 * Fix: OrderStatus에 리뷰 완료 상태 >> isReviewed 멤버 변수로 변경 * Design: review 작성 여부와 order status에 따른 UI 변경 * Design: review 작성 여부와 order status에 따른 UI 변경 * Feat: navigation 이벤트 추가 * Design: 디자인 마진 변경 * 동기화 (#178) * Design: 공백 수정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Release 1.0.0(18) 출시 (#147) * Feature-Magazine Init * Chore: Manifest 정리 * Chore: 기본 의존성 설정 * Chore: Test 관련 의존성 정리 * Chore: Compose 설정 * Feat: Response Dto 추가 * Feat: Magazine Screen 추가 * Feat: Magazine Service 추가 * Feat: Magazine Service DI 추가 * Resource: Floating Action Button Open Icon 추가 * Feat: Magazine DataStore 추가 * Fix: Response 타입 수정 * Feat: Data Store DI * Feat: Repository DI * Feat: Magazine Repository 추가 * Feat: 최신 향수 받아오는 API 추가 * Feat: 최신 향수 받아오는 DTO 추가 * Resource: 공유 아이콘 추가 * Feat: Magazine ViewModel 로직 추가 * Design: TopBar 투명도 파라미터 추가 * Rename: 파일 명 변경 * Design: 투명도 추가 * Design: Magazine Tag 추가 * Resource: 아이콘 resource 추가 * Fix: Response 타입 변경 * Chore: Magazine 의존성 추가 * Feat: Magazine Navigation 추가 * Fix: Bottom Navigation 내용 변경 * Feat: Magazine 상세 화면 추가 * Feat: Magazine Paging 추가 * Feat: Magazine Route 클래스 추가 * Feat: Magazine 상세 비즈니스 로직 추가 * Fix: Conflict 수정 * Fix: Paging 오류 수정 * Design: title 색상 파라미터 추가 * Design: title 색상 파라미터 추가 * Design: review content 위치 변경 * Design: Content 글자 수 제한 * Design: title 글자 수 제한 * Fix: 개행문자 수정 * Feat: Navigation 이벤트 추가 * Feat: Magazine 상세 화면 추가 * Feat: Magazine 상세 화면 비즈니스 로직 추가 * Feat: Navigation 이벤트 추가 * Fix: 데이터 순서에 따른 오류 수정 * Design: Tag UI 수정 * Design: Space 크기 조절 * Feat: 좋아요 update 이벤트 추가 * Fix: Navigation 이벤트 파라미터 추가 * Feat: Navigation 이벤트 파라미터 추가 * Design: Magazine UI 위치 수정 * Fix: Magazine Image 추가 * Resource: Magazine Icon 추가 * Design: 바텀 네비게이션 UI 수정 * Feat: Navigation SingleTop 옵션 추가 * Feat: 좋아요 한 향수 페이지 위치 변동 * FIX: 비로그인 에러다이얼로그 동작 오류 수정 * Fix: Navigation 누락 오류 수정 * Fix: err state 누락 오류 수정 * Fix: navigation 누락 수정 * Design: UI 간격 수정 * Gradle: Material 의존성 추가 * Design: 수정 모달 추가 * Refactor: Dialog 팝업 방식 변경 * FIX: 좋아요 리프레싱 시 리컴포지션 안되는 오류 수정 * Rename: 이름 혼동 방지 * Rename: 이름 혼동 방지 * Fix: Dialog Pop up 시 깜빡거림 수정 * Feat: 향수페이지 댓글 오류 수정 * Fix: 향수 페이지 댓글 상태관리 변화 오류 수정 * Delete: 사용하지 않는 상태관리 변수 삭제 * Update README.md * Resource: Font 추가 * Create android.yml develop 브랜치로 코드 푸시, PR 시 빌드되는 기능 * Feat: 자동 빌드 기능 테스트 구문 * Update android.yml * Feat: 자바 버전 11 -> 17 * Fix: CI환경 빌드에 local.properties 파일 동적 생성 기능 추가 * Fix: 경로 오류 수정 * Feat: 모든 모듈의 local-properties파일 삭제 명령파일 생성 * Fix: app 모듈왜 local.properties를 사용하는 모듈도 파일 동적생성 적용 * Chore: 서브 모듈 추가 * Delete: mylibrary 모듈 삭제 * Chore: AndroidSecretSecure 서브 레포지토리 추가 * Revert "Delete: mylibrary 모듈 삭제" This reverts commit cc0c0fd6d21b7f3d941ed11ab515ff2bf6b8e8ab. * Revert "Chore: 서브 모듈 추가" This reverts commit 95cc85845823843a72eb29a6b65a001b99947c6f. * Fix: 소셜 토큰 api 호출 오류 수정 * Ignore * Fix: lateinit 삭제 및 초기화 값 지정 * Fix: IndexOutOfBoundException방지 구문 추가 * Chore: google-service.json 파일 추가 * Rename * Chore: NATIVE_APP_KEY 적용 * Chore: 버전 증가 6->7 * Feat: 토큰 유무 검사 로직 수정 * Feat: 토큰 가져오는 비동기 작업 -> 동기로 변경 * Fix: 토큰 갱신 작업 대기방식을 동기적으로 변경 * Fix: 스트림 닫힘 오류 원인 부분 해결 * Revert "Feat: 토큰 가져오는 비동기 작업 -> 동기로 변경" This reverts commit f56f46f1000603260a6f143dd4304ffc1b4750bf. * Fix: postFcmToken NullPointException 원인구문 삭제 * Fix: 인터셉터 토큰 추가동작 수정 비동기 -> 동기 * Chore: v1.0.0 버전코드 수정 (7->8) * Fix: native app key, string value로 변경 * Fix: HttpLoggingInterceptor 제거 - IllgalStateException 해결을 위해 지워봄 * Refactor: HPediaDesc api호출 분리 및 CastException 해결 * Chore: 버전코드 수정(8->9) * Chore: 버전코드 수정 (9->10) * Fix: 변수 명 오류 * Chore: 버전코드 수정(10->11) * Fix: 카카오 앱 키 참조 방식 변경 * Chore: 버전코드 수정(11->12) * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Chore: core-common 의존성 추가 * Delete: 토큰 재발급 임시 로직 삭제 * HotFix: Authenticator 토큰 재발급 및 에러메세지 전달 기능 수정 * Fix: Authenticator 적용 * Fix: api 호출부에 Authenticator 적용 * Delete: 안쓰는 api 삭제 * Refactor: FCM 초기화 및 초기 라우팅 코드 함수로 분리 * Delete: 임시 refreshToken 코드 관련 api 삭제 * Rename: 토큰 관련 클래스 의존성 주입 모듈 이름 수정 * Fix: 토큰 동적 할당 시점 변경 * Fix: 로그인 화면 이동 네비게이션 변경 * Chore: 버전 변경 (v1.1.1 -> v1.1.2) * Chore: ci,cd 구문 변경 및 action.yml 파일 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: ci/cd 워크플로우 임시로 주석처리 및 사용중지 * Chore: android.yml 워크플로우 일시중지 (#164) * Chore: CI 구문 롤백 및 오작동 CI/CD 임시폴더로 분리 * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 * v1.1.1 버전 master로 머지합니다 (#163) * Feat: Fcm 관련 함수 추가 * Chore: FCM 모듈 의존성 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Chore: fcm 모듈 환경 설정 추가 * Feat: App Navigation 이벤트 추가 * Chore: FCM 모듈 환경 설정 * Resource: 아이콘 추가 * Feat: 알림 수신 여부 이벤트 추가 * Feat: 알림 화면 추가 * Feat: 알림 화면 비즈니스 로직 추가 * Feat: FCM 모듈 추가 * Feat: 알림 Response 모델 추가 * Feat: 알림 화면 네비게이션 추가 * Design: 읽음 여부에 따른 배경색 조절 * Test: 테스트 코드 추가 * Feat: App Scheme 추가 * Feat: Deeplink Navigation 추가 * Ignore * Delete: sample-app 모듈 삭제 * Delete: Hhmoa_android_secret 로컬 폴더 삭제 * Design: Button 컴포넌트 disabled color 이름 적용 * Feat: Hbti설문 아이템 컴포넌트 추가 * Feat: ProgressBar 컴포넌트 생성 * Feat: VerticalStepBar 컴포넌트 생성 * Design: 홈화면 상단 로고 아이콘 추가 * Design: 디자인시스템 모듈 내 컴포넌트에 pretendard 폰트 적용 * Feat: profile 속성 추가 * Feat: send top notification 파라미터 수정 * Feat: profile 속성 추가 * Chore: Activity single top 속성 설정 * Fix: Error Ui State 업데이트 안되는 오류 수정 * Feat: deeplink 처리 함수 추가 * Refactor: Community, HPedia 네비게이션 분리 * Refactor: Community, HPedia 네비게이션 분리 * Feat: deeplink 설정 * Fix: 경로 설정 오류 수정 * Fix: deeplink 위치 오류 수정 * Fix: Response Dto 형식 오류 수정 * Design: Profile 반영 * Feat: 선택 이벤트 추가 * Feat: Navigation 설정 * Feat: 읽음 처리 함수 추가 * Fix: read 변경 가능하도록 수정 * Test: import 수정 * ignore: git pull * Design: 색상 변경 * Feat: NoteImageItem 생성 * Feat: 권한 설정 여부 정보를 확인 * Feat: 권한 설정 함수 추가 * Ignore * Ignore * Feat: feature-hbti 모듈 생성 * Feat:선택지 무효화 기능 추가 및 SurveyOptionList로 수정 * Rename: SurveyOptionItem -> SurveyOptionList * Feat: ProgressBarPreview에 +/- 효과 추가 * Chore: gradle 의존성 추가 * Fix: intent 이름 변경 * Feat: 알림 선택 시 읽음 처리 이벤트 추가 * Feat: 포그라운드 알림 처리 * Fix: Navigation Deeplink 오류 수정 * Chore: mockito 라이브러리 추가 * Feat: HbtiScreen 추가 * Chore: compose material 및 preview 라이브러리 추가 * Feat: Hbti화면 완성 * Design: 향BTI 화면 디자인 구성 완료 * Feat: 향BTI 테스트 데이터계층 클래스 생성 * Rename: SurveyAnswerResponseDto -> SurveyOptionResponseDto * Feat: fcm token 저장 함수 추가 * Fix: 파라미터 이름 오류 수정 * Fix: 토큰 저장 알고리즘 수정 * Feat: 향수 추천 화면 추가 * Design: 공백 수정 * Feat: 데이터 계층 hilt 주입코드 추가 * Feat: HbtiSurvey 화면 추가(미완성) * Feat: 가격 선택 화면 추가 * Design: 아이템 간 간격 조절 * Rename: 컴포넌트 이름 변경 * Rename: 컴포넌트 이름 변경 * Feat: 향료 선택 화면 추가 * Refactor: 화면 구성 변경 * Fix: 파라미터 변경 * Resource: icon 추가 * Fix: 파라미터 수정 * Feat: 향료 선택 화면 추가 * Style: 공백 스타일 변경 * Fix: 푸쉬 오류 수정 * Style: 코드 스타일 변경 * Feat: 향수 추천 결과 화면 추가 * Rename: 컴포넌트 이름 변경 * Ignore * Delete * Chore: test 라이브러리 추가 * Feat: HbtiSurveyViewmodel 생성 * Test: HbtiSurveyViewModel 테스트 생성 * Test: 테스트 기대값 수정 * Feat: Dto 추가 * Feat: Api 추가 * Style: 코드 라인 변경 * Feat: 비즈니스 로직 추가 * Remove: 삭제 * Feat: 향료 데이터 클래스 추가 * Comment: 주석 추가 * Fix: 서버에 정보 전달 로직 임의 대체 * Rename: 함수 명 변경 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: UI 상태 기준 분기 * Feat: Navigation 설정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: android.yml 워크플로우 일시중지 (#164) * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Fix: 파라미터 명시적으로 구분 * Fix: RouteScreen 파라미터 변수명 변경 반영 * Chore: 버전코드 수정 22->23 * Ignore * Fix: 백업데이터 설정 해제 * Chore: 버전 업데이트 * Release 1.1.2버전 master로 푸시 (#167) * Feat: Fcm 관련 함수 추가 * Chore: FCM 모듈 의존성 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Chore: fcm 모듈 환경 설정 추가 * Feat: App Navigation 이벤트 추가 * Chore: FCM 모듈 환경 설정 * Resource: 아이콘 추가 * Feat: 알림 수신 여부 이벤트 추가 * Feat: 알림 화면 추가 * Feat: 알림 화면 비즈니스 로직 추가 * Feat: FCM 모듈 추가 * Feat: 알림 Response 모델 추가 * Feat: 알림 화면 네비게이션 추가 * Design: 읽음 여부에 따른 배경색 조절 * Test: 테스트 코드 추가 * Feat: App Scheme 추가 * Feat: Deeplink Navigation 추가 * Ignore * Delete: sample-app 모듈 삭제 * Delete: Hhmoa_android_secret 로컬 폴더 삭제 * Design: Button 컴포넌트 disabled color 이름 적용 * Feat: Hbti설문 아이템 컴포넌트 추가 * Feat: ProgressBar 컴포넌트 생성 * Feat: VerticalStepBar 컴포넌트 생성 * Design: 홈화면 상단 로고 아이콘 추가 * Design: 디자인시스템 모듈 내 컴포넌트에 pretendard 폰트 적용 * Feat: profile 속성 추가 * Feat: send top notification 파라미터 수정 * Feat: profile 속성 추가 * Chore: Activity single top 속성 설정 * Fix: Error Ui State 업데이트 안되는 오류 수정 * Feat: deeplink 처리 함수 추가 * Refactor: Community, HPedia 네비게이션 분리 * Refactor: Community, HPedia 네비게이션 분리 * Feat: deeplink 설정 * Fix: 경로 설정 오류 수정 * Fix: deeplink 위치 오류 수정 * Fix: Response Dto 형식 오류 수정 * Design: Profile 반영 * Feat: 선택 이벤트 추가 * Feat: Navigation 설정 * Feat: 읽음 처리 함수 추가 * Fix: read 변경 가능하도록 수정 * Test: import 수정 * ignore: git pull * Design: 색상 변경 * Feat: NoteImageItem 생성 * Feat: 권한 설정 여부 정보를 확인 * Feat: 권한 설정 함수 추가 * Ignore * Ignore * Feat: feature-hbti 모듈 생성 * Feat:선택지 무효화 기능 추가 및 SurveyOptionList로 수정 * Rename: SurveyOptionItem -> SurveyOptionList * Feat: ProgressBarPreview에 +/- 효과 추가 * Chore: gradle 의존성 추가 * Fix: intent 이름 변경 * Feat: 알림 선택 시 읽음 처리 이벤트 추가 * Feat: 포그라운드 알림 처리 * Fix: Navigation Deeplink 오류 수정 * Chore: mockito 라이브러리 추가 * Feat: HbtiScreen 추가 * Chore: compose material 및 preview 라이브러리 추가 * Feat: Hbti화면 완성 * Design: 향BTI 화면 디자인 구성 완료 * Feat: 향BTI 테스트 데이터계층 클래스 생성 * Rename: SurveyAnswerResponseDto -> SurveyOptionResponseDto * Feat: fcm token 저장 함수 추가 * Fix: 파라미터 이름 오류 수정 * Fix: 토큰 저장 알고리즘 수정 * Feat: 향수 추천 화면 추가 * Design: 공백 수정 * Feat: 데이터 계층 hilt 주입코드 추가 * Feat: HbtiSurvey 화면 추가(미완성) * Feat: 가격 선택 화면 추가 * Design: 아이템 간 간격 조절 * Rename: 컴포넌트 이름 변경 * Rename: 컴포넌트 이름 변경 * Feat: 향료 선택 화면 추가 * Refactor: 화면 구성 변경 * Fix: 파라미터 변경 * Resource: icon 추가 * Fix: 파라미터 수정 * Feat: 향료 선택 화면 추가 * Style: 공백 스타일 변경 * Fix: 푸쉬 오류 수정 * Style: 코드 스타일 변경 * Feat: 향수 추천 결과 화면 추가 * Rename: 컴포넌트 이름 변경 * Ignore * Delete * Chore: test 라이브러리 추가 * Feat: HbtiSurveyViewmodel 생성 * Test: HbtiSurveyViewModel 테스트 생성 * Test: 테스트 기대값 수정 * Feat: Dto 추가 * Feat: Api 추가 * Style: 코드 라인 변경 * Feat: 비즈니스 로직 추가 * Remove: 삭제 * Feat: 향료 데이터 클래스 추가 * Comment: 주석 추가 * Fix: 서버에 정보 전달 로직 임의 대체 * Rename: 함수 명 변경 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: UI 상태 기준 분기 * Feat: Navigation 설정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: android.yml 워크플로우 일시중지 (#164) * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Revert "Chore: 버전 업데이트" This reverts commit 031fc2f141d3ffbc07b0954eda874c58d7e1c834. * Revert "Fix: 백업데이터 설정 해제" This reverts commit bb68a8d265be89d74bcc2feed66baca5355cd475. * HotFix: 카카오 sdk 버전 업그레이드 * HotFix: 카카오 sdk 버전 업그레이드 (#170) * HotFix: 카카오 sdk 버전 업그레이드 * Feat: gradlew clean 작업 추가 * Delete * Delete: refreshToken 추상메서드 삭제 * Delete: 토큰 리프레싱 임시방안 코드 삭제 * HotFix: 카카오 sdk 버전 업그레이드 (#174) * Hotfix/community (#176) * Fix: 좋아요 반영 안되는 오류 수정 * Fix: response에 wrapping 추가 * Design: 내용 및 사진 누락 추가 * Fix: response wrapping * Design: 디자인 누락 추가 * Refactor: 불필요 로직 삭제 * Feat: 파라미터 명 변경 * Design: 버튼 가려지는 현상 수정 * Fix: hbti 향료개수 자유선택 후 튕기는 현상 수정 * Fix: hbti 향료 선택결과 제출로직 변경 * Fix: hbti 향료선택화면 하단버튼 disabled 상태관리 추가 * Fix: hbti 향료 카테고리 선택화면 로직 변경 반영 * Test: hbti 향료 카테고리 선택화면 로직 변경사항 테스트 * Design: 백버튼 추가 * Feat: 향료 제품 가격 추가 * Refactor: 플래그 제거 및 콜백으로 대체 * Design: 디자인 마진 변경 --------- Co-authored-by: Lee YongIn <67788699+LeeYongIn0517@users.noreply.github.com> Co-authored-by: 이용인 * Design: Topbar 배경 수정 * Feat: hbti 홈화면 메타데이터 추가 및 기존 데이터 리팩토링 * Design: 홈 디자인 변경 반영 * Design: Topbar 디폴트 배경 변경 * Feat: 로그인 유무 확인 코드 추가 * Design: 스크롤 초기 위치 수정 * Chore: 버전 코드 변경 (24 -> 25) * Design: 향모아 사업자 정보 추가 * Fix: hbti 메타데이터 요청 오류 임시 주석처리 * Chore: 데이터백업설정 변경 * Chore: 테스트 버전 업그레이드 25->27 * Test/1.1.4(27) 내부테스트 추가사항 (#179) * Chore: 데이터백업설정 변경 * Chore: 테스트 버전 업그레이드 25->27 * Fix: 주소지 추가 오류 수정 (#180) * Chore: 삭제할 local properties 목록 추가 * Design: 환불 반품 내역 확인 UI 추가 * Design: 결제 완료 화면 UI 추가 * Feat: order result 경로 추가 * Feat: order result 화면 navigation 추가 * Feat: order result 화면 navigation 추가 * Feat: navigation 이벤트 추가 * Feat: navigation 이벤트 추가 * Feat: 결제 완료 후 order result 화면으로 이동 * Feat: navigation 이벤트 추가 * Fix: index out of range 오류 수정 * Feat: 부트페이 결제 화면 close 함수 추가 * Fix: return 위치로 인한 로직 오류 수정 * Feat: kakao 1대1 채팅 이벤트 추가 * Design: 이용 약관 UI 제거 * Feat: 주문 내역 get 메서드 추가 * Feat: 주문 상태 Enum Class 추가 * Feat: 주문 내역 response dto 추가 * Remove: 미사용 클래스 삭제 * Feat: 환불 api 추가 * Feat: 배송 상태 번역 함수 추가 * Fix: 파라미터 타입 변경 (String >> Note) * Feat: api response에 따른 파라미터 타입 변경 * Feat: 주문 내역, 환불 화면 navigation graph에 추가 * Feat: 주문 내역 화면 비즈니스 로직과 연결 * Feat: 환불 신청 화면 비즈니스 로직과 연결 * Feat: 환불 신청 화면 비즈니스 로직 추가 * Feat: 주문 내역 비즈니스 로직 추가 * Fix: 파라미터 변경에 따른 수정 (String >> Note) * Feat: 주문 내역, 환불 화면 route graph에 추가 * Feat: 주문 내역 navigation 이벤트 추가 * Feat: 주문 내역 navigation 이벤트 추가 * Fix: 파라미터 타입 변경 (Not Null >> Nullable) * Fix: filter not 동작 오류 수정 * Fix: 가격 계산 로직 변경 * Fix: 엘비스 연산 처리 추가 * Fix: 파라미터 matching 실수 수정 * Design: 여백 조정 * Rename: 파라미터 명 변경 * Feat: 환불 api 완료 후에 이전 화면으로 navigation 되도록 설정 * Feat: 가격 계산 관련 비즈니스 로직 수정 * Comment: Log 삭제 * Feat: Web Link 연결에서 Web View 사용으로 변경 * Remove: 미사용 UI 삭제 * Feat: 파라미터 타입 변경 (not null >> nullable) * Feat: 파라미터 값 null 여부에 따른 UI 분기 * Rename: navigation route 클래스 위치 이동 (각 feature 모듈 >> core-domain.entity) * Rename: navigation route 클래스 위치 이동 (각 feature 모듈 >> core-domain.entity) * Rename: navigation 이벤트 명 변경 * Rename: navigation 이벤트 명 변경 * Rename: navigation 이벤트 명 변경 * Rename: entity 위치 변경 (각 feature 모듈 & core-model >> core-domain) * Feat: decode from string import 누락 추가 * Feat: decode from string import 누락 추가 * Feat: 주문 내역 조회 paging 처리 * Feat: nullable 처리 * Rename: 파라미터 명 변경 * Chore: 의존성 중복 제거 * Rename: 파라미터 이름 변경 * Fix: 파라미터 변경 * Rename: navigation 이벤트 명 변경 * Rename: 화면 명 변경 * Feat: 환불/반품 내역 조회 api 추가 * Rename: 함수 이름 변경 (getRefund >> getRefundRecord) * Rename: 함수 이름 변경 (getFavoriteCommentPaging >> getOrderRecordPaging) * Rename: 파일 명 변경 (ReturnOrRefundRecordPage >> RefundRecordPage) * Feat: 반품/환불 내역 비즈니스 로직 추가 * Feat: Empty Data Page 컴포넌트 추가 * Feat: view model 연결 * Feat: view model 추가 * Feat: view model 연결 * Fix: 패키지 명 다른 오류 수정 * Remove: 미사용 resource 삭제 * Rename: 디렉토리 명 변경 (Screen >> screen) * Feat: import 문 정리 * Rename: 패키지 명 변경 적용 * Rename: 패키지 명 변경 적용 * Design: padding 조절 * Fix: Response Dto 변경 * Feat: 환불 내역 조회 response 모델 추가 * Feat: response 변경에 따른 createAt 정보 추가 * Feat: navigation 이벤트 추가 * Feat: navigation 이벤트 추가 * Feat: order status 취소 완료 상태 추가 * Feat: order status 반품 완료 상태 추가 * Fix: UI 배송비 누락 수정 * Fix: UI 배송비 누락 수정 * Feat: 반품 완료 상태 추가 * Fix: 배송비 UI 누락 수정 * Design: UI 정렬 * Design: 버튼 삭제 * Remove: 미사용 화면 삭제 * Feat: NoDataPage >> EmptyDataPage 변경 * Design: font 적용 * Remove: 미사용 import 문 제거 * Rename: 파라미터 명 변경 * Feat: 반품 진행 중 상태 추가 * Feat: order status를 기준으로 Button UI 분기 * Feat: 반품 진행 중 상태 추가 * Feat: 리뷰 작성 navigation 이벤트 추가 * Comment: 임의 이벤트 주석 추가 * Rename: 파일 위치 이동 (like 모듈 >> userInfo 모듈) * Rename: navigation 이벤트 명 변경 * Feat: 좋아요 한 향수 화면 route 추가 * Feat: navigation 이벤트 추가 * Remove: like 모듈 삭제 및 user info 모듈 병합 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Ignore: git pull * Test: sort 로직 test * Feat: Paging 내 sort 추가 * Remove: 미사용 resource 삭제 * Fix: 카테고리 내용 변경 (시향기 >> 향BTI 시향기) * Refactor: 변수 위치 변경 * Revert * Ignore: git pull * Ignore: git pull * Feat: 리뷰 컴포넌트 추가 * Feat: 선택 시 사진 확대 추가 * Feat: 선택 시 사진 확대 추가 * Design: 색상 반전 여부 추가 * Feat: int RequestBody형으로 변환 함수 추가 * Chore: decode string 함수 의존성 추가 * Feat: 리뷰 관련 dto 추가 * Feat: photo dto 추가 * Feat: h shop review 관련 api 추가 * Feat: h shop review 관련 api 추가 * Feat: 좋아요 개수 파라미터 추가 * Design: 반전 여부 추가 * Feat: review 화면 추가 * Feat: path 변환 함수 (local uri >> absolute path) * Feat: get my orders api 추가 * Feat: get my orders dto 추가 * Feat: 리뷰 작성 view model 추가 * Feat: 리뷰 작성 화면 view model 연결 * Chore: json decode import 추가 * Feat: 리뷰 작성 navigation 추가 * Fix: FAB 버튼 파라미터 변경 (고정 값 >> 변동 값) * Rename: my orders api 위치 변경 (HShop >> HShopReview) * Feat: 파라미터 타입 변경 (() -> Unit >> Unit) * Feat: navigation 이벤트 추가 * Chore: paging 의존성 추가 * Fix: val >> var * Feat: 선택 가능 여부 설정 파라미터 추가 * Feat: paging 클래스 추가 * Feat: 리뷰 화면 view model 추가 * Feat: 리뷰 화면 view model 연결 * Feat: HBTI 홈 view model 추가 * Design: 테두리 색상 남는 UI 수정 * Design: navigation icon 색상 값 추가 * Style: 코드 스타일 변경 * Feat: navigation 이벤트 추가 * Design: 디자인 파라미터 변경 * Design: 글 색 변경 * Feat: 리뷰 UI 추가 * Design: FAB 디자인 변경 * Design: FAB padding 변경 * Design: icon 색상 변경 * Design: FAB 디자인 변경 * Design: text 변경 * Design: TopBar 색상 변경 * Design: FAB 선택 시 배경 애니메이션 추가 * Design: 컴포넌트 색상 명시 * Feat: 성능 개선을 위한 분리 * Fix: public >> private * Feat: 신고, 삭제 이름 선언 * Feat: 삭제, 신고 이벤트 추가 * Fix: ui 성능 개선 * Remove: 불필요 변수 제거 * Remove: 불필요 변수 제거 * Fix: var >> val * Fix: 좋아요 로직 변경 * Feat: navigation 이벤트 추가 * Chore: material 의존성 추가 * Feat: 좋아요 이벤트 추가 * Feat: 좋아요, 삭제, 신고 기능 추가 * Feat: 수정 api 추가 * Feat: 리뷰 수정 화면 추가 * Feat: 리뷰 수정 비즈니스 로직 추가 * Feat: 리뷰 수정 화면 네비게이션 연결 * Ignore * Design: FAB 버튼 테두리 삭제 * Fix: navigation 이벤트 호출 수정 * Feat: 리뷰 단건 조회, 삭제 api 추가 * Feat: FAB option 변수 값 변경 * Feat: delete review 함수 연결 * Fix: part 어노테이션 네이밍 오류 수정 * Fix: 함수 파라미터 변경 * Fix: 함수 파라미터 변경 * Feat: 삭제 후 ui 반영되도록 flag 추가 * Fix: delay 시간 축소 * Remove: log 삭제 * Design: 아이콘 변경 * Design: 스크롤 범위 전체로 변경 * Feat: 개별 navigation 람다 적용 * Feat: 개별 navigation 람다 적용 * Fix: Part 어노테이션 이름 추가 * Feat: 리뷰 수정 화면 navigation 연결 * Feat: single top 옵션 추가 * Design: 배경 이미지 추가 * Feat: 신고 기능 추가 * Feat: 리뷰 신고 api 추가 * Fix: 파라미터 명 변경 * Style: 코드 줄 변경 * Feat: 이벤트 후 dialog 닫기 * Feat: 작성한 리뷰 navigation 연결 * Rename: getMyOrders api 위치 이동 (hShopReview >> HShop) * Feat: 내가 작성한 review api 추가 * Feat: 내가 작성한 review 화면 추가 * Feat: 내가 작성한 review view model 추가 * Feat: 내 review paging source * Feat: 내 review 화면 연결 * Rename: paging source 위치 이동 * Feat: 리뷰 완료 상태 추가 * Feat: navigation 이벤트 추가 * Feat: createdAt 멤버 변수 추가 * Design: 클릭 범위 변경 * Design: 클릭 범위 변경 * Feat: navigation 파라미터 추가 * Feat: 환불 버튼 클릭 시 dialog 생성 * Design: fontSize, lineHeight 조정 * Design: 날짜 추가, 색상 변경 * Remove: 미사용 dto 삭제 * Fix: OrderStatus에 리뷰 완료 상태 >> isReviewed 멤버 변수로 변경 * Design: review 작성 여부와 order status에 따른 UI 변경 * Design: review 작성 여부와 order status에 따른 UI 변경 * Feat: navigation 이벤트 추가 * Design: 텍스트 문구 변경 * Fix: navigation 경로 수정 * Fix: review 사용 조건 변경 * Design: top bar 배경 색상 변경 * Refactor: 중복 함수 제거 * Fix: 닉네임 중복 확인 api 변경 반영 * Remove: 불필요 파라미터 제거 * Refactor: Recomposition 줄도록 수정 * Fix: 느린 상태 update 수정 * Fix: 느린 상태 update 수정 * Refactor: recomposition 감소 유도 * Ignore: Merge * Design: top bar 색상 추가 * Fix: 배송 요청을 선택 사항으로 변경 * Design: 단일 매거진 Pager로 변경 * chore: gitignore 파일 추가 * chore: 주석해제 * Feat: 상품 구매 여부 확인 다이얼로그 추가 * Feat: Hbti 설문 양옆 스크롤 기능 추가 * Delete: 주석 삭제 * Fix: LazyColumn으로 변경 후 스크롤위치 초기화 적용 * 향BTI 기능 누락 추가 및 피드백 반영 (#181) * Chore: 데이터백업설정 변경 * Chore: 테스트 버전 업그레이드 25->27 * chore: gitignore 파일 추가 * chore: 주석해제 * Feat: 상품 구매 여부 확인 다이얼로그 추가 * Feat: Hbti 설문 양옆 스크롤 기능 추가 * Delete: 주석 삭제 * Fix: LazyColumn으로 변경 후 스크롤위치 초기화 적용 * Feature/hbti shj (#182) * Feat: 배송 상태 번역 함수 추가 * Fix: 파라미터 타입 변경 (String >> Note) * Feat: api response에 따른 파라미터 타입 변경 * Feat: 주문 내역, 환불 화면 navigation graph에 추가 * Feat: 주문 내역 화면 비즈니스 로직과 연결 * Feat: 환불 신청 화면 비즈니스 로직과 연결 * Feat: 환불 신청 화면 비즈니스 로직 추가 * Feat: 주문 내역 비즈니스 로직 추가 * Fix: 파라미터 변경에 따른 수정 (String >> Note) * Feat: 주문 내역, 환불 화면 route graph에 추가 * Feat: 주문 내역 navigation 이벤트 추가 * Feat: 주문 내역 navigation 이벤트 추가 * Fix: 파라미터 타입 변경 (Not Null >> Nullable) * Fix: filter not 동작 오류 수정 * Fix: 가격 계산 로직 변경 * Fix: 엘비스 연산 처리 추가 * Fix: 파라미터 matching 실수 수정 * Design: 여백 조정 * Rename: 파라미터 명 변경 * Feat: 환불 api 완료 후에 이전 화면으로 navigation 되도록 설정 * Feat: 가격 계산 관련 비즈니스 로직 수정 * Comment: Log 삭제 * Feat: Web Link 연결에서 Web View 사용으로 변경 * Remove: 미사용 UI 삭제 * Feat: 파라미터 타입 변경 (not null >> nullable) * Feat: 파라미터 값 null 여부에 따른 UI 분기 * Rename: navigation route 클래스 위치 이동 (각 feature 모듈 >> core-domain.entity) * Rename: navigation route 클래스 위치 이동 (각 feature 모듈 >> core-domain.entity) * Rename: navigation 이벤트 명 변경 * Rename: navigation 이벤트 명 변경 * Rename: navigation 이벤트 명 변경 * Rename: entity 위치 변경 (각 feature 모듈 & core-model >> core-domain) * Feat: decode from string import 누락 추가 * Feat: decode from string import 누락 추가 * Feat: 주문 내역 조회 paging 처리 * Feat: nullable 처리 * Rename: 파라미터 명 변경 * Chore: 의존성 중복 제거 * Rename: 파라미터 이름 변경 * Fix: 파라미터 변경 * Rename: navigation 이벤트 명 변경 * Rename: 화면 명 변경 * Feat: 환불/반품 내역 조회 api 추가 * Rename: 함수 이름 변경 (getRefund >> getRefundRecord) * Rename: 함수 이름 변경 (getFavoriteCommentPaging >> getOrderRecordPaging) * Rename: 파일 명 변경 (ReturnOrRefundRecordPage >> RefundRecordPage) * Feat: 반품/환불 내역 비즈니스 로직 추가 * Feat: Empty Data Page 컴포넌트 추가 * Feat: view model 연결 * Feat: view model 추가 * Feat: view model 연결 * Fix: 패키지 명 다른 오류 수정 * Remove: 미사용 resource 삭제 * Rename: 디렉토리 명 변경 (Screen >> screen) * Feat: import 문 정리 * Rename: 패키지 명 변경 적용 * Rename: 패키지 명 변경 적용 * Design: padding 조절 * Fix: Response Dto 변경 * Feat: 환불 내역 조회 response 모델 추가 * Feat: response 변경에 따른 createAt 정보 추가 * Feat: navigation 이벤트 추가 * Feat: navigation 이벤트 추가 * Feat: order status 취소 완료 상태 추가 * Feat: order status 반품 완료 상태 추가 * Fix: UI 배송비 누락 수정 * Fix: UI 배송비 누락 수정 * Feat: 반품 완료 상태 추가 * Fix: 배송비 UI 누락 수정 * Design: UI 정렬 * Design: 버튼 삭제 * Remove: 미사용 화면 삭제 * Feat: NoDataPage >> EmptyDataPage 변경 * Design: font 적용 * Remove: 미사용 import 문 제거 * Rename: 파라미터 명 변경 * Feat: 반품 진행 중 상태 추가 * Feat: order status를 기준으로 Button UI 분기 * Feat: 반품 진행 중 상태 추가 * Feat: 리뷰 작성 navigation 이벤트 추가 * Comment: 임의 이벤트 주석 추가 * Rename: 파일 위치 이동 (like 모듈 >> userInfo 모듈) * Rename: navigation 이벤트 명 변경 * Feat: 좋아요 한 향수 화면 route 추가 * Feat: navigation 이벤트 추가 * Remove: like 모듈 삭제 및 user info 모듈 병합 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Ignore: git pull * Test: sort 로직 test * Feat: Paging 내 sort 추가 * Remove: 미사용 resource 삭제 * Fix: 카테고리 내용 변경 (시향기 >> 향BTI 시향기) * Refactor: 변수 위치 변경 * Revert * Ignore: git pull * Ignore: git pull * Feat: 리뷰 컴포넌트 추가 * Feat: 선택 시 사진 확대 추가 * Feat: 선택 시 사진 확대 추가 * Design: 색상 반전 여부 추가 * Feat: int RequestBody형으로 변환 함수 추가 * Chore: decode string 함수 의존성 추가 * Feat: 리뷰 관련 dto 추가 * Feat: photo dto 추가 * Feat: h shop review 관련 api 추가 * Feat: h shop review 관련 api 추가 * Feat: 좋아요 개수 파라미터 추가 * Design: 반전 여부 추가 * Feat: review 화면 추가 * Feat: path 변환 함수 (local uri >> absolute path) * Feat: get my orders api 추가 * Feat: get my orders dto 추가 * Feat: 리뷰 작성 view model 추가 * Feat: 리뷰 작성 화면 view model 연결 * Chore: json decode import 추가 * Feat: 리뷰 작성 navigation 추가 * Fix: FAB 버튼 파라미터 변경 (고정 값 >> 변동 값) * Rename: my orders api 위치 변경 (HShop >> HShopReview) * Feat: 파라미터 타입 변경 (() -> Unit >> Unit) * Feat: navigation 이벤트 추가 * Chore: paging 의존성 추가 * Fix: val >> var * Feat: 선택 가능 여부 설정 파라미터 추가 * Feat: paging 클래스 추가 * Feat: 리뷰 화면 view model 추가 * Feat: 리뷰 화면 view model 연결 * Feat: HBTI 홈 view model 추가 * Design: 테두리 색상 남는 UI 수정 * Design: navigation icon 색상 값 추가 * Style: 코드 스타일 변경 * Feat: navigation 이벤트 추가 * Design: 디자인 파라미터 변경 * Design: 글 색 변경 * Feat: 리뷰 UI 추가 * Design: FAB 디자인 변경 * Design: FAB padding 변경 * Design: icon 색상 변경 * Design: FAB 디자인 변경 * Design: text 변경 * Design: TopBar 색상 변경 * Design: FAB 선택 시 배경 애니메이션 추가 * Design: 컴포넌트 색상 명시 * Feat: 성능 개선을 위한 분리 * Fix: public >> private * Feat: 신고, 삭제 이름 선언 * Feat: 삭제, 신고 이벤트 추가 * Fix: ui 성능 개선 * Remove: 불필요 변수 제거 * Remove: 불필요 변수 제거 * Fix: var >> val * Fix: 좋아요 로직 변경 * Feat: navigation 이벤트 추가 * Chore: material 의존성 추가 * Feat: 좋아요 이벤트 추가 * Feat: 좋아요, 삭제, 신고 기능 추가 * Feat: 수정 api 추가 * Feat: 리뷰 수정 화면 추가 * Feat: 리뷰 수정 비즈니스 로직 추가 * Feat: 리뷰 수정 화면 네비게이션 연결 * Ignore * Design: FAB 버튼 테두리 삭제 * Fix: navigation 이벤트 호출 수정 * Feat: 리뷰 단건 조회, 삭제 api 추가 * Feat: FAB option 변수 값 변경 * Feat: delete review 함수 연결 * Fix: part 어노테이션 네이밍 오류 수정 * Fix: 함수 파라미터 변경 * Fix: 함수 파라미터 변경 * Feat: 삭제 후 ui 반영되도록 flag 추가 * Fix: delay 시간 축소 * Remove: log 삭제 * Design: 아이콘 변경 * Design: 스크롤 범위 전체로 변경 * Feat: 개별 navigation 람다 적용 * Feat: 개별 navigation 람다 적용 * Fix: Part 어노테이션 이름 추가 * Feat: 리뷰 수정 화면 navigation 연결 * Feat: single top 옵션 추가 * Design: 배경 이미지 추가 * Feat: 신고 기능 추가 * Feat: 리뷰 신고 api 추가 * Fix: 파라미터 명 변경 * Style: 코드 줄 변경 * Feat: 이벤트 후 dialog 닫기 * Feat: 작성한 리뷰 navigation 연결 * Rename: getMyOrders api 위치 이동 (hShopReview >> HShop) * Feat: 내가 작성한 review api 추가 * Feat: 내가 작성한 review 화면 추가 * Feat: 내가 작성한 review view model 추가 * Feat: 내 review paging source * Feat: 내 review 화면 연결 * Rename: paging source 위치 이동 * Feat: 리뷰 완료 상태 추가 * Feat: navigation 이벤트 추가 * Feat: createdAt 멤버 변수 추가 * Design: 클릭 범위 변경 * Design: 클릭 범위 변경 * Feat: navigation 파라미터 추가 * Feat: 환불 버튼 클릭 시 dialog 생성 * Design: fontSize, lineHeight 조정 * Design: 날짜 추가, 색상 변경 * Remove: 미사용 dto 삭제 * Fix: OrderStatus에 리뷰 완료 상태 >> isReviewed 멤버 변수로 변경 * Design: review 작성 여부와 order status에 따른 UI 변경 * Design: review 작성 여부와 order status에 따른 UI 변경 * Feat: navigation 이벤트 추가 * Design: 텍스트 문구 변경 * Fix: navigation 경로 수정 * Fix: review 사용 조건 변경 * Design: top bar 배경 색상 변경 * Refactor: 중복 함수 제거 * Fix: 닉네임 중복 확인 api 변경 반영 * Remove: 불필요 파라미터 제거 * Refactor: Recomposition 줄도록 수정 * Fix: 느린 상태 update 수정 * Fix: 느린 상태 update 수정 * Refactor: recomposition 감소 유도 * Ignore: Merge * Design: top bar 색상 추가 * Fix: 배송 요청을 선택 사항으로 변경 * Design: 단일 매거진 Pager로 변경 * Feat: ResultResponse Wrapping * Feat: nav login 네비게이션 이벤트 추가 * Refactor: Recomposition 감소 * Refactor: Recomposition 감소 * Feat: authenticator 추가 * Feat: authenticator 추가 * Style: 여백 삭제 * Design: 테두리 추가 * Refactor: Recomposition 감소 * Rename: 파라미터 명 변경 * Refactor: Recomposition 감소 * Refactor: Recomposition 감소 * Fix: NullPointerException 오류 수정 * Design: 버튼 색상 변경 * Design: 뒤고 가기 버튼 삭제 * Feat: navigation 도착지 변경 (홈 >> Hbti 홈) * Feat: navigation stack 정리 * Feat: navigation stack 정리 * Fix: Nickname Input 컴포넌트 파라미터 변경에 따른 수정 * Refactor: isNoteSelectedData상태 업데이트 함수 수정 * fix: Hbti ProgressBar 리컴포지션 최적화 및 UI 버그 개선 * Design: Hbti 향료 선택화면 디테일 변경 * Fix: nullable 처리 누락 수정 * Feature/hbti 버그 및 HBTI UI 수정 (#183) * Design: 공백 수정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Release 1.0.0(18) 출시 (#147) * Feature-Magazine Init * Chore: Manifest 정리 * Chore: 기본 의존성 설정 * Chore: Test 관련 의존성 정리 * Chore: Compose 설정 * Feat: Response Dto 추가 * Feat: Magazine Screen 추가 * Feat: Magazine Service 추가 * Feat: Magazine Service DI 추가 * Resource: Floating Action Button Open Icon 추가 * Feat: Magazine DataStore 추가 * Fix: Response 타입 수정 * Feat: Data Store DI * Feat: Repository DI * Feat: Magazine Repository 추가 * Feat: 최신 향수 받아오는 API 추가 * Feat: 최신 향수 받아오는 DTO 추가 * Resource: 공유 아이콘 추가 * Feat: Magazine ViewModel 로직 추가 * Design: TopBar 투명도 파라미터 추가 * Rename: 파일 명 변경 * Design: 투명도 추가 * Design: Magazine Tag 추가 * Resource: 아이콘 resource 추가 * Fix: Response 타입 변경 * Chore: Magazine 의존성 추가 * Feat: Magazine Navigation 추가 * Fix: Bottom Navigation 내용 변경 * Feat: Magazine 상세 화면 추가 * Feat: Magazine Paging 추가 * Feat: Magazine Route 클래스 추가 * Feat: Magazine 상세 비즈니스 로직 추가 * Fix: Conflict 수정 * Fix: Paging 오류 수정 * Design: title 색상 파라미터 추가 * Design: title 색상 파라미터 추가 * Design: review content 위치 변경 * Design: Content 글자 수 제한 * Design: title 글자 수 제한 * Fix: 개행문자 수정 * Feat: Navigation 이벤트 추가 * Feat: Magazine 상세 화면 추가 * Feat: Magazine 상세 화면 비즈니스 로직 추가 * Feat: Navigation 이벤트 추가 * Fix: 데이터 순서에 따른 오류 수정 * Design: Tag UI 수정 * Design: Space 크기 조절 * Feat: 좋아요 update 이벤트 추가 * Fix: Navigation 이벤트 파라미터 추가 * Feat: Navigation 이벤트 파라미터 추가 * Design: Magazine UI 위치 수정 * Fix: Magazine Image 추가 * Resource: Magazine Icon 추가 * Design: 바텀 네비게이션 UI 수정 * Feat: Navigation SingleTop 옵션 추가 * Feat: 좋아요 한 향수 페이지 위치 변동 * FIX: 비로그인 에러다이얼로그 동작 오류 수정 * Fix: Navigation 누락 오류 수정 * Fix: err state 누락 오류 수정 * Fix: navigation 누락 수정 * Design: UI 간격 수정 * Gradle: Material 의존성 추가 * Design: 수정 모달 추가 * Refactor: Dialog 팝업 방식 변경 * FIX: 좋아요 리프레싱 시 리컴포지션 안되는 오류 수정 * Rename: 이름 혼동 방지 * Rename: 이름 혼동 방지 * Fix: Dialog Pop up 시 깜빡거림 수정 * Feat: 향수페이지 댓글 오류 수정 * Fix: 향수 페이지 댓글 상태관리 변화 오류 수정 * Delete: 사용하지 않는 상태관리 변수 삭제 * Update README.md * Resource: Font 추가 * Create android.yml develop 브랜치로 코드 푸시, PR 시 빌드되는 기능 * Feat: 자동 빌드 기능 테스트 구문 * Update android.yml * Feat: 자바 버전 11 -> 17 * Fix: CI환경 빌드에 local.properties 파일 동적 생성 기능 추가 * Fix: 경로 오류 수정 * Feat: 모든 모듈의 local-properties파일 삭제 명령파일 생성 * Fix: app 모듈왜 local.properties를 사용하는 모듈도 파일 동적생성 적용 * Chore: 서브 모듈 추가 * Delete: mylibrary 모듈 삭제 * Chore: AndroidSecretSecure 서브 레포지토리 추가 * Revert "Delete: mylibrary 모듈 삭제" This reverts commit cc0c0fd6d21b7f3d941ed11ab515ff2bf6b8e8ab. * Revert "Chore: 서브 모듈 추가" This reverts commit 95cc85845823843a72eb29a6b65a001b99947c6f. * Fix: 소셜 토큰 api 호출 오류 수정 * Ignore * Fix: lateinit 삭제 및 초기화 값 지정 * Fix: IndexOutOfBoundException방지 구문 추가 * Chore: google-service.json 파일 추가 * Rename * Chore: NATIVE_APP_KEY 적용 * Chore: 버전 증가 6->7 * Feat: 토큰 유무 검사 로직 수정 * Feat: 토큰 가져오는 비동기 작업 -> 동기로 변경 * Fix: 토큰 갱신 작업 대기방식을 동기적으로 변경 * Fix: 스트림 닫힘 오류 원인 부분 해결 * Revert "Feat: 토큰 가져오는 비동기 작업 -> 동기로 변경" This reverts commit f56f46f1000603260a6f143dd4304ffc1b4750bf. * Fix: postFcmToken NullPointException 원인구문 삭제 * Fix: 인터셉터 토큰 추가동작 수정 비동기 -> 동기 * Chore: v1.0.0 버전코드 수정 (7->8) * Fix: native app key, string value로 변경 * Fix: HttpLoggingInterceptor 제거 - IllgalStateException 해결을 위해 지워봄 * Refactor: HPediaDesc api호출 분리 및 CastException 해결 * Chore: 버전코드 수정(8->9) * Chore: 버전코드 수정 (9->10) * Fix: 변수 명 오류 * Chore: 버전코드 수정(10->11) * Fix: 카카오 앱 키 참조 방식 변경 * Chore: 버전코드 수정(11->12) * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Chore: core-common 의존성 추가 * Delete: 토큰 재발급 임시 로직 삭제 * HotFix: Authenticator 토큰 재발급 및 에러메세지 전달 기능 수정 * Fix: Authenticator 적용 * Fix: api 호출부에 Authenticator 적용 * Delete: 안쓰는 api 삭제 * Refactor: FCM 초기화 및 초기 라우팅 코드 함수로 분리 * Delete: 임시 refreshToken 코드 관련 api 삭제 * Rename: 토큰 관련 클래스 의존성 주입 모듈 이름 수정 * Fix: 토큰 동적 할당 시점 변경 * Fix: 로그인 화면 이동 네비게이션 변경 * Chore: 버전 변경 (v1.1.1 -> v1.1.2) * Chore: ci,cd 구문 변경 및 action.yml 파일 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: ci/cd 워크플로우 임시로 주석처리 및 사용중지 * Chore: android.yml 워크플로우 일시중지 (#164) * Chore: CI 구문 롤백 및 오작동 CI/CD 임시폴더로 분리 * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 * v1.1.1 버전 master로 머지합니다 (#163) * Feat: Fcm 관련 함수 추가 * Chore: FCM 모듈 의존성 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Chore: fcm 모듈 환경 설정 추가 * Feat: App Navigation 이벤트 추가 * Chore: FCM 모듈 환경 설정 * Resource: 아이콘 추가 * Feat: 알림 수신 여부 이벤트 추가 * Feat: 알림 화면 추가 * Feat: 알림 화면 비즈니스 로직 추가 * Feat: FCM 모듈 추가 * Feat: 알림 Response 모델 추가 * Feat: 알림 화면 네비게이션 추가 * Design: 읽음 여부에 따른 배경색 조절 * Test: 테스트 코드 추가 * Feat: App Scheme 추가 * Feat: Deeplink Navigation 추가 * Ignore * Delete: sample-app 모듈 삭제 * Delete: Hhmoa_android_secret 로컬 폴더 삭제 * Design: Button 컴포넌트 disabled color 이름 적용 * Feat: Hbti설문 아이템 컴포넌트 추가 * Feat: ProgressBar 컴포넌트 생성 * Feat: VerticalStepBar 컴포넌트 생성 * Design: 홈화면 상단 로고 아이콘 추가 * Design: 디자인시스템 모듈 내 컴포넌트에 pretendard 폰트 적용 * Feat: profile 속성 추가 * Feat: send top notification 파라미터 수정 * Feat: profile 속성 추가 * Chore: Activity single top 속성 설정 * Fix: Error Ui State 업데이트 안되는 오류 수정 * Feat: deeplink 처리 함수 추가 * Refactor: Community, HPedia 네비게이션 분리 * Refactor: Community, HPedia 네비게이션 분리 * Feat: deeplink 설정 * Fix: 경로 설정 오류 수정 * Fix: deeplink 위치 오류 수정 * Fix: Response Dto 형식 오류 수정 * Design: Profile 반영 * Feat: 선택 이벤트 추가 * Feat: Navigation 설정 * Feat: 읽음 처리 함수 추가 * Fix: read 변경 가능하도록 수정 * Test: import 수정 * ignore: git pull * Design: 색상 변경 * Feat: NoteImageItem 생성 * Feat: 권한 설정 여부 정보를 확인 * Feat: 권한 설정 함수 추가 * Ignore * Ignore * Feat: feature-hbti 모듈 생성 * Feat:선택지 무효화 기능 추가 및 SurveyOptionList로 수정 * Rename: SurveyOptionItem -> SurveyOptionList * Feat: ProgressBarPreview에 +/- 효과 추가 * Chore: gradle 의존성 추가 * Fix: intent 이름 변경 * Feat: 알림 선택 시 읽음 처리 이벤트 추가 * Feat: 포그라운드 알림 처리 * Fix: Navigation Deeplink 오류 수정 * Chore: mockito 라이브러리 추가 * Feat: HbtiScreen 추가 * Chore: compose material 및 preview 라이브러리 추가 * Feat: Hbti화면 완성 * Design: 향BTI 화면 디자인 구성 완료 * Feat: 향BTI 테스트 데이터계층 클래스 생성 * Rename: SurveyAnswerResponseDto -> SurveyOptionResponseDto * Feat: fcm token 저장 함수 추가 * Fix: 파라미터 이름 오류 수정 * Fix: 토큰 저장 알고리즘 수정 * Feat: 향수 추천 화면 추가 * Design: 공백 수정 * Feat: 데이터 계층 hilt 주입코드 추가 * Feat: HbtiSurvey 화면 추가(미완성) * Feat: 가격 선택 화면 추가 * Design: 아이템 간 간격 조절 * Rename: 컴포넌트 이름 변경 * Rename: 컴포넌트 이름 변경 * Feat: 향료 선택 화면 추가 * Refactor: 화면 구성 변경 * Fix: 파라미터 변경 * Resource: icon 추가 * Fix: 파라미터 수정 * Feat: 향료 선택 화면 추가 * Style: 공백 스타일 변경 * Fix: 푸쉬 오류 수정 * Style: 코드 스타일 변경 * Feat: 향수 추천 결과 화면 추가 * Rename: 컴포넌트 이름 변경 * Ignore * Delete * Chore: test 라이브러리 추가 * Feat: HbtiSurveyViewmodel 생성 * Test: HbtiSurveyViewModel 테스트 생성 * Test: 테스트 기대값 수정 * Feat: Dto 추가 * Feat: Api 추가 * Style: 코드 라인 변경 * Feat: 비즈니스 로직 추가 * Remove: 삭제 * Feat: 향료 데이터 클래스 추가 * Comment: 주석 추가 * Fix: 서버에 정보 전달 로직 임의 대체 * Rename: 함수 명 변경 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: UI 상태 기준 분기 * Feat: Navigation 설정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: android.yml 워크플로우 일시중지 (#164) * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Fix: 파라미터 명시적으로 구분 * Fix: RouteScreen 파라미터 변수명 변경 반영 * Chore: 버전코드 수정 22->23 * Ignore * Fix: 백업데이터 설정 해제 * Chore: 버전 업데이트 * Release 1.1.2버전 master로 푸시 (#167) * Feat: Fcm 관련 함수 추가 * Chore: FCM 모듈 의존성 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Chore: fcm 모듈 환경 설정 추가 * Feat: App Navigation 이벤트 추가 * Chore: FCM 모듈 환경 설정 * Resource: 아이콘 추가 * Feat: 알림 수신 여부 이벤트 추가 * Feat: 알림 화면 추가 * Feat: 알림 화면 비즈니스 로직 추가 * Feat: FCM 모듈 추가 * Feat: 알림 Response 모델 추가 * Feat: 알림 화면 네비게이션 추가 * Design: 읽음 여부에 따른 배경색 조절 * Test: 테스트 코드 추가 * Feat: App Scheme 추가 * Feat: Deeplink Navigation 추가 * Ignore * Delete: sample-app 모듈 삭제 * Delete: Hhmoa_android_secret 로컬 폴더 삭제 * Design: Button 컴포넌트 disabled color 이름 적용 * Feat: Hbti설문 아이템 컴포넌트 추가 * Feat: ProgressBar 컴포넌트 생성 * Feat: VerticalStepBar 컴포넌트 생성 * Design: 홈화면 상단 로고 아이콘 추가 * Design: 디자인시스템 모듈 내 컴포넌트에 pretendard 폰트 적용 * Feat: profile 속성 추가 * Feat: send top notification 파라미터 수정 * Feat: profile 속성 추가 * Chore: Activity single top 속성 설정 * Fix: Error Ui State 업데이트 안되는 오류 수정 * Feat: deeplink 처리 함수 추가 * Refactor: Community, HPedia 네비게이션 분리 * Refactor: Community, HPedia 네비게이션 분리 * Feat: deeplink 설정 * Fix: 경로 설정 오류 수정 * Fix: deeplink 위치 오류 수정 * Fix: Response Dto 형식 오류 수정 * Design: Profile 반영 * Feat: 선택 이벤트 추가 * Feat: Navigation 설정 * Feat: 읽음 처리 함수 추가 * Fix: read 변경 가능하도록 수정 * Test: import 수정 * ignore: git pull * Design: 색상 변경 * Feat: NoteImageItem 생성 * Feat: 권한 설정 여부 정보를 확인 * Feat: 권한 설정 함수 추가 * Ignore * Ignore * Feat: feature-hbti 모듈 생성 * Feat:선택지 무효화 기능 추가 및 SurveyOptionList로 수정 * Rename: SurveyOptionItem -> SurveyOptionList * Feat: ProgressBarPreview에 +/- 효과 추가 * Chore: gradle 의존성 추가 * Fix: intent 이름 변경 * Feat: 알림 선택 시 읽음 처리 이벤트 추가 * Feat: 포그라운드 알림 처리 * Fix: Navigation Deeplink 오류 수정 * Chore: mockito 라이브러리 추가 * Feat: HbtiScreen 추가 * Chore: compose material 및 preview 라이브러리 추가 * Feat: Hbti화면 완성 * Design: 향BTI 화면 디자인 구성 완료 * Feat: 향BTI 테스트 데이터계층 클래스 생성 * Rename: SurveyAnswerResponseDto -> SurveyOptionResponseDto * Feat: fcm token 저장 함수 추가 * Fix: 파라미터 이름 오류 수정 * Fix: 토큰 저장 알고리즘 수정 * Feat: 향수 추천 화면 추가 * Design: 공백 수정 * Feat: 데이터 계층 hilt 주입코드 추가 * Feat: HbtiSurvey 화면 추가(미완성) * Feat: 가격 선택 화면 추가 * Design: 아이템 간 간격 조절 * Rename: 컴포넌트 이름 변경 * Rename: 컴포넌트 이름 변경 * Feat: 향료 선택 화면 추가 * Refactor: 화면 구성 변경 * Fix: 파라미터 변경 * Resource: icon 추가 * Fix: 파라미터 수정 * Feat: 향료 선택 화면 추가 * Style: 공백 스타일 변경 * Fix: 푸쉬 오류 수정 * Style: 코드 스타일 변경 * Feat: 향수 추천 결과 화면 추가 * Rename: 컴포넌트 이름 변경 * Ignore * Delete * Chore: test 라이브러리 추가 * Feat: HbtiSurveyViewmodel 생성 * Test: HbtiSurveyViewModel 테스트 생성 * Test: 테스트 기대값 수정 * Feat: Dto 추가 * Feat: Api 추가 * Style: 코드 라인 변경 * Feat: 비즈니스 로직 추가 * Remove: 삭제 * Feat: 향료 데이터 클래스 추가 * Comment: 주석 추가 * Fix: 서버에 정보 전달 로직 임의 대체 * Rename: 함수 명 변경 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: UI 상태 기준 분기 * Feat: Navigation 설정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: android.yml 워크플로우 일시중지 (#164) * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Revert "Chore: 버전 업데이트" This reverts commit 031fc2f141d3ffbc07b0954eda874c58d7e1c834. * Revert "Fix: 백업데이터 설정 해제" This reverts commit bb68a8d265be89d74bcc2feed66baca5355cd475. * HotFix: 카카오 sdk 버전 업그레이드 * HotFix: 카카오 sdk 버전 업그레이드 (#170) * HotFix: 카카오 sdk 버전 업그레이드 * Feat: gradlew clean 작업 추가 * Delete * Delete: refreshToken 추상메서드 삭제 * Delete: 토큰 리프레싱 임시방안 코드 삭제 * HotFix: 카카오 sdk 버전 업그레이드 (#174) * Hotfix/community (#176) * Fix: 좋아요 반영 안되는 오류 수정 * Fix: response에 wrapping 추가 * Design: 내용 및 사진 누락 추가 * Fix: response wrapping * Design: 디자인 누락 추가 * Refactor: 불필요 로직 삭제 * Feat: 파라미터 명 변경 * Design: 버튼 가려지는 현상 수정 * Fix: hbti 향료개수 자유선택 후 튕기는 현상 수정 * Fix: hbti 향료 선택결과 제출로직 변경 * Fix: hbti 향료선택화면 하단버튼 disabled 상태관리 추가 * Fix: hbti 향료 카테고리 선택화면 로직 변경 반영 * Test: hbti 향료 카테고리 선택화면 로직 변경사항 테스트 * Design: 백버튼 추가 * Feat: 향료 제품 가격 추가 * Refactor: 플래그 제거 및 콜백으로 대체 * Design: 디자인 마진 변경 * Design: Topbar 배경 수정 * Feat: hbti 홈화면 메타데이터 추가 및 기존 데이터 리팩토링 * Design: 홈 디자인 변경 반영 * Design: Topbar 디폴트 배경 변경 * Feat: 로그인 유무 확인 코드 추가 * Design: 스크롤 초기 위치 수정 * Chore: 버전 코드 변경 (24 -> 25) * Design: 향모아 사업자 정보 추가 * Fix: hbti 메타데이터 요청 오류 임시 주석처리 * Chore: 데이터백업설정 변경 * Chore: 테스트 버전 업그레이드 25->27 * chore: gitignore 파일 추가 * chore: 주석해제 * Feat: 상품 구매 여부 확인 다이얼로그 추가 * Feat: Hbti 설문 양옆 스크롤 기능 추가 * Delete: 주석 삭제 * Fix: LazyColumn으로 변경 후 스크롤위치 초기화 적용 * Refactor: isNoteSelectedData상태 업데이트 함수 수정 * fix: Hbti ProgressBar 리컴포지션 최적화 및 UI 버그 개선 * Design: Hbti 향료 선택화면 디테일 변경 * Fix: nullable 처리 누락 수정 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Feat: 향료주문 과정 설명 화면 api 적용 * Feat: 향료주문 과정 설명 화면 네비게이션 추가 * Feat: 가격대 향수추천 결과 화면 추가 * Test: 향수 추천결과 화면 UI/단위 테스트 작성 * Test: 뷰모델 변경사항 반영한 테스트 수정 * Fix: 브랜드 이미지 삭제 반영 * Design: 상단 바 패딩 불일치 수정 * Fix: 향수 화면의 브랜드 사진 삭제 반영 * Feature/hbti HBTI 디자인 최종 수정 반영 (#184) * Design: 공백 수정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Release 1.0.0(18) 출시 (#147) * Feature-Magazine Init * Chore: Manifest 정리 * Chore: 기본 의존성 설정 * Chore: Test 관련 의존성 정리 * Chore: Compose 설정 * Feat: Response Dto 추가 * Feat: Magazine Screen 추가 * Feat: Magazine Service 추가 * Feat: Magazine Service DI 추가 * Resource: Floating Action Button Open Icon 추가 * Feat: Magazine DataStore 추가 * Fix: Response 타입 수정 * Feat: Data Store DI * Feat: Repository DI * Feat: Magazine Repository 추가 * Feat: 최신 향수 받아오는 API 추가 * Feat: 최신 향수 받아오는 DTO 추가 * Resource: 공유 아이콘 추가 * Feat: Magazine ViewModel 로직 추가 * Design: TopBar 투명도 파라미터 추가 * Rename: 파일 명 변경 * Design: 투명도 추가 * Design: Magazine Tag 추가 * Resource: 아이콘 resource 추가 * Fix: Response 타입 변경 * Chore: Magazine 의존성 추가 * Feat: Magazine Navigation 추가 * Fix: Bottom Navigation 내용 변경 * Feat: Magazine 상세 화면 추가 * Feat: Magazine Paging 추가 * Feat: Magazine Route 클래스 추가 * Feat: Magazine 상세 비즈니스 로직 추가 * Fix: Conflict 수정 * Fix: Paging 오류 수정 * Design: title 색상 파라미터 추가 * Design: title 색상 파라미터 추가 * Design: review content 위치 변경 * Design: Content 글자 수 제한 * Design: title 글자 수 제한 * Fix: 개행문자 수정 * Feat: Navigation 이벤트 추가 * Feat: Magazine 상세 화면 추가 * Feat: Magazine 상세 화면 비즈니스 로직 추가 * Feat: Navigation 이벤트 추가 * Fix: 데이터 순서에 따른 오류 수정 * Design: Tag UI 수정 * Design: Space 크기 조절 * Feat: 좋아요 update 이벤트 추가 * Fix: Navigation 이벤트 파라미터 추가 * Feat: Navigation 이벤트 파라미터 추가 * Design: Magazine UI 위치 수정 * Fix: Magazine Image 추가 * Resource: Magazine Icon 추가 * Design: 바텀 네비게이션 UI 수정 * Feat: Navigation SingleTop 옵션 추가 * Feat: 좋아요 한 향수 페이지 위치 변동 * FIX: 비로그인 에러다이얼로그 동작 오류 수정 * Fix: Navigation 누락 오류 수정 * Fix: err state 누락 오류 수정 * Fix: navigation 누락 수정 * Design: UI 간격 수정 * Gradle: Material 의존성 추가 * Design: 수정 모달 추가 * Refactor: Dialog 팝업 방식 변경 * FIX: 좋아요 리프레싱 시 리컴포지션 안되는 오류 수정 * Rename: 이름 혼동 방지 * Rename: 이름 혼동 방지 * Fix: Dialog Pop up 시 깜빡거림 수정 * Feat: 향수페이지 댓글 오류 수정 * Fix: 향수 페이지 댓글 상태관리 변화 오류 수정 * Delete: 사용하지 않는 상태관리 변수 삭제 * Update README.md * Resource: Font 추가 * Create android.yml develop 브랜치로 코드 푸시, PR 시 빌드되는 기능 * Feat: 자동 빌드 기능 테스트 구문 * Update android.yml * Feat: 자바 버전 11 -> 17 * Fix: CI환경 빌드에 local.properties 파일 동적 생성 기능 추가 * Fix: 경로 오류 수정 * Feat: 모든 모듈의 local-properties파일 삭제 명령파일 생성 * Fix: app 모듈왜 local.properties를 사용하는 모듈도 파일 동적생성 적용 * Chore: 서브 모듈 추가 * Delete: mylibrary 모듈 삭제 * Chore: AndroidSecretSecure 서브 레포지토리 추가 * Revert "Delete: mylibrary 모듈 삭제" This reverts commit cc0c0fd6d21b7f3d941ed11ab515ff2bf6b8e8ab. * Revert "Chore: 서브 모듈 추가" This reverts commit 95cc85845823843a72eb29a6b65a001b99947c6f. * Fix: 소셜 토큰 api 호출 오류 수정 * Ignore * Fix: lateinit 삭제 및 초기화 값 지정 * Fix: IndexOutOfBoundException방지 구문 추가 * Chore: google-service.json 파일 추가 * Rename * Chore: NATIVE_APP_KEY 적용 * Chore: 버전 증가 6->7 * Feat: 토큰 유무 검사 로직 수정 * Feat: 토큰 가져오는 비동기 작업 -> 동기로 변경 * Fix: 토큰 갱신 작업 대기방식을 동기적으로 변경 * Fix: 스트림 닫힘 오류 원인 부분 해결 * Revert "Feat: 토큰 가져오는 비동기 작업 -> 동기로 변경" This reverts commit f56f46f1000603260a6f143dd4304ffc1b4750bf. * Fix: postFcmToken NullPointException 원인구문 삭제 * Fix: 인터셉터 토큰 추가동작 수정 비동기 -> 동기 * Chore: v1.0.0 버전코드 수정 (7->8) * Fix: native app key, string value로 변경 * Fix: HttpLoggingInterceptor 제거 - IllgalStateException 해결을 위해 지워봄 * Refactor: HPediaDesc api호출 분리 및 CastException 해결 * Chore: 버전코드 수정(8->9) * Chore: 버전코드 수정 (9->10) * Fix: 변수 명 오류 * Chore: 버전코드 수정(10->11) * Fix: 카카오 앱 키 참조 방식 변경 * Chore: 버전코드 수정(11->12) * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Chore: core-common 의존성 추가 * Delete: 토큰 재발급 임시 로직 삭제 * HotFix: Authenticator 토큰 재발급 및 에러메세지 전달 기능 수정 * Fix: Authenticator 적용 * Fix: api 호출부에 Authenticator 적용 * Delete: 안쓰는 api 삭제 * Refactor: FCM 초기화 및 초기 라우팅 코드 함수로 분리 * Delete: 임시 refreshToken 코드 관련 api 삭제 * Rename: 토큰 관련 클래스 의존성 주입 모듈 이름 수정 * Fix: 토큰 동적 할당 시점 변경 * Fix: 로그인 화면 이동 네비게이션 변경 * Chore: 버전 변경 (v1.1.1 -> v1.1.2) * Chore: ci,cd 구문 변경 및 action.yml 파일 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: ci/cd 워크플로우 임시로 주석처리 및 사용중지 * Chore: android.yml 워크플로우 일시중지 (#164) * Chore: CI 구문 롤백 및 오작동 CI/CD 임시폴더로 분리 * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 * v1.1.1 버전 master로 머지합니다 (#163) * Feat: Fcm 관련 함수 추가 * Chore: FCM 모듈 의존성 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Chore: fcm 모듈 환경 설정 추가 * Feat: App Navigation 이벤트 추가 * Chore: FCM 모듈 환경 설정 * Resource: 아이콘 추가 * Feat: 알림 수신 여부 이벤트 추가 * Feat: 알림 화면 추가 * Feat: 알림 화면 비즈니스 로직 추가 * Feat: FCM 모듈 추가 * Feat: 알림 Response 모델 추가 * Feat: 알림 화면 네비게이션 추가 * Design: 읽음 여부에 따른 배경색 조절 * Test: 테스트 코드 추가 * Feat: App Scheme 추가 * Feat: Deeplink Navigation 추가 * Ignore * Delete: sample-app 모듈 삭제 * Delete: Hhmoa_android_secret 로컬 폴더 삭제 * Design: Button 컴포넌트 disabled color 이름 적용 * Feat: Hbti설문 아이템 컴포넌트 추가 * Feat: ProgressBar 컴포넌트 생성 * Feat: VerticalStepBar 컴포넌트 생성 * Design: 홈화면 상단 로고 아이콘 추가 * Design: 디자인시스템 모듈 내 컴포넌트에 pretendard 폰트 적용 * Feat: profile 속성 추가 * Feat: send top notification 파라미터 수정 * Feat: profile 속성 추가 * Chore: Activity single top 속성 설정 * Fix: Error Ui State 업데이트 안되는 오류 수정 * Feat: deeplink 처리 함수 추가 * Refactor: Community, HPedia 네비게이션 분리 * Refactor: Community, HPedia 네비게이션 분리 * Feat: deeplink 설정 * Fix: 경로 설정 오류 수정 * Fix: deeplink 위치 오류 수정 * Fix: Response Dto 형식 오류 수정 * Design: Profile 반영 * Feat: 선택 이벤트 추가 * Feat: Navigation 설정 * Feat: 읽음 처리 함수 추가 * Fix: read 변경 가능하도록 수정 * Test: import 수정 * ignore: git pull * Design: 색상 변경 * Feat: NoteImageItem 생성 * Feat: 권한 설정 여부 정보를 확인 * Feat: 권한 설정 함수 추가 * Ignore * Ignore * Feat: feature-hbti 모듈 생성 * Feat:선택지 무효화 기능 추가 및 SurveyOptionList로 수정 * Rename: SurveyOptionItem -> SurveyOptionList * Feat: ProgressBarPreview에 +/- 효과 추가 * Chore: gradle 의존성 추가 * Fix: intent 이름 변경 * Feat: 알림 선택 시 읽음 처리 이벤트 추가 * Feat: 포그라운드 알림 처리 * Fix: Navigation Deeplink 오류 수정 * Chore: mockito 라이브러리 추가 * Feat: HbtiScreen 추가 * Chore: compose material 및 preview 라이브러리 추가 * Feat: Hbti화면 완성 * Design: 향BTI 화면 디자인 구성 완료 * Feat: 향BTI 테스트 데이터계층 클래스 생성 * Rename: SurveyAnswerResponseDto -> SurveyOptionResponseDto * Feat: fcm token 저장 함수 추가 * Fix: 파라미터 이름 오류 수정 * Fix: 토큰 저장 알고리즘 수정 * Feat: 향수 추천 화면 추가 * Design: 공백 수정 * Feat: 데이터 계층 hilt 주입코드 추가 * Feat: HbtiSurvey 화면 추가(미완성) * Feat: 가격 선택 화면 추가 * Design: 아이템 간 간격 조절 * Rename: 컴포넌트 이름 변경 * Rename: 컴포넌트 이름 변경 * Feat: 향료 선택 화면 추가 * Refactor: 화면 구성 변경 * Fix: 파라미터 변경 * Resource: icon 추가 * Fix: 파라미터 수정 * Feat: 향료 선택 화면 추가 * Style: 공백 스타일 변경 * Fix: 푸쉬 오류 수정 * Style: 코드 스타일 변경 * Feat: 향수 추천 결과 화면 추가 * Rename: 컴포넌트 이름 변경 * Ignore * Delete * Chore: test 라이브러리 추가 * Feat: HbtiSurveyViewmodel 생성 * Test: HbtiSurveyViewModel 테스트 생성 * Test: 테스트 기대값 수정 * Feat: Dto 추가 * Feat: Api 추가 * Style: 코드 라인 변경 * Feat: 비즈니스 로직 추가 * Remove: 삭제 * Feat: 향료 데이터 클래스 추가 * Comment: 주석 추가 * Fix: 서버에 정보 전달 로직 임의 대체 * Rename: 함수 명 변경 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: UI 상태 기준 분기 * Feat: Navigation 설정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: android.yml 워크플로우 일시중지 (#164) * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Fix: 파라미터 명시적으로 구분 * Fix: RouteScreen 파라미터 변수명 변경 반영 * Chore: 버전코드 수정 22->23 * Ignore * Fix: 백업데이터 설정 해제 * Chore: 버전 업데이트 * Release 1.1.2버전 master로 푸시 (#167) * Feat: Fcm 관련 함수 추가 * Chore: FCM 모듈 의존성 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Chore: fcm 모듈 환경 설정 추가 * Feat: App Navigation 이벤트 추가 * Chore: FCM 모듈 환경 설정 * Resource: 아이콘 추가 * Feat: 알림 수신 여부 이벤트 추가 * Feat: 알림 화면 추가 * Feat: 알림 화면 비즈니스 로직 추가 * Feat: FCM 모듈 추가 * Feat: 알림 Response 모델 추가 * Feat: 알림 화면 네비게이션 추가 * Design: 읽음 여부에 따른 배경색 조절 * Test: 테스트 코드 추가 * Feat: App Scheme 추가 * Feat: Deeplink Navigation 추가 * Ignore * Delete: sample-app 모듈 삭제 * Delete: Hhmoa_android_secret 로컬 폴더 삭제 * Design: Button 컴포넌트 disabled color 이름 적용 * Feat: Hbti설문 아이템 컴포넌트 추가 * Feat: ProgressBar 컴포넌트 생성 * Feat: VerticalStepBar 컴포넌트 생성 * Design: 홈화면 상단 로고 아이콘 추가 * Design: 디자인시스템 모듈 내 컴포넌트에 pretendard 폰트 적용 * Feat: profile 속성 추가 * Feat: send top notification 파라미터 수정 * Feat: profile 속성 추가 * Chore: Activity single top 속성 설정 * Fix: Error Ui State 업데이트 안되는 오류 수정 * Feat: deeplink 처리 함수 추가 * Refactor: Community, HPedia 네비게이션 분리 * Refactor: Community, HPedia 네비게이션 분리 * Feat: deeplink 설정 * Fix: 경로 설정 오류 수정 * Fix: deeplink 위치 오류 수정 * Fix: Response Dto 형식 오류 수정 * Design: Profile 반영 * Feat: 선택 이벤트 추가 * Feat: Navigation 설정 * Feat: 읽음 처리 함수 추가 * Fix: read 변경 가능하도록 수정 * Test: import 수정 * ignore: git pull * Design: 색상 변경 * Feat: NoteImageItem 생성 * Feat: 권한 설정 여부 정보를 확인 * Feat: 권한 설정 함수 추가 * Ignore * Ignore * Feat: feature-hbti 모듈 생성 * Feat:선택지 무효화 기능 추가 및 SurveyOptionList로 수정 * Rename: SurveyOptionItem -> SurveyOptionList * Feat: ProgressBarPreview에 +/- 효과 추가 * Chore: gradle 의존성 추가 * Fix: intent 이름 변경 * Feat: 알림 선택 시 읽음 처리 이벤트 추가 * Feat: 포그라운드 알림 처리 * Fix: Navigation Deeplink 오류 수정 * Chore: mockito 라이브러리 추가 * Feat: HbtiScreen 추가 * Chore: compose material 및 preview 라이브러리 추가 * Feat: Hbti화면 완성 * Design: 향BTI 화면 디자인 구성 완료 * Feat: 향BTI 테스트 데이터계층 클래스 생성 * Rename: SurveyAnswerResponseDto -> SurveyOptionResponseDto * Feat: fcm token 저장 함수 추가 * Fix: 파라미터 이름 오류 수정 * Fix: 토큰 저장 알고리즘 수정 * Feat: 향수 추천 화면 추가 * Design: 공백 수정 * Feat: 데이터 계층 hilt 주입코드 추가 * Feat: HbtiSurvey 화면 추가(미완성) * Feat: 가격 선택 화면 추가 * Design: 아이템 간 간격 조절 * Rename: 컴포넌트 이름 변경 * Rename: 컴포넌트 이름 변경 * Feat: 향료 선택 화면 추가 * Refactor: 화면 구성 변경 * Fix: 파라미터 변경 * Resource: icon 추가 * Fix: 파라미터 수정 * Feat: 향료 선택 화면 추가 * Style: 공백 스타일 변경 * Fix: 푸쉬 오류 수정 * Style: 코드 스타일 변경 * Feat: 향수 추천 결과 화면 추가 * Rename: 컴포넌트 이름 변경 * Ignore * Delete * Chore: test 라이브러리 추가 * Feat: HbtiSurveyViewmodel 생성 * Test: HbtiSurveyViewModel 테스트 생성 * Test: 테스트 기대값 수정 * Feat: Dto 추가 * Feat: Api 추가 * Style: 코드 라인 변경 * Feat: 비즈니스 로직 추가 * Remove: 삭제 * Feat: 향료 데이터 클래스 추가 * Comment: 주석 추가 * Fix: 서버에 정보 전달 로직 임의 대체 * Rename: 함수 명 변경 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: UI 상태 기준 분기 * Feat: Navigation 설정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: android.yml 워크플로우 일시중지 (#164) * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Revert "Chore: 버전 업데이트" This reverts commit 031fc2f141d3ffbc07b0954eda874c58d7e1c834. * Revert "Fix: 백업데이터 설정 해제" This reverts commit bb68a8d265be89d74bcc2feed66baca5355cd475. * HotFix: 카카오 sdk 버전 업그레이드 * HotFix: 카카오 sdk 버전 업그레이드 (#170) * HotFix: 카카오 sdk 버전 업그레이드 * Feat: gradlew clean 작업 추가 * Delete * Delete: refreshToken 추상메서드 삭제 * Delete: 토큰 리프레싱 임시방안 코드 삭제 * HotFix: 카카오 sdk 버전 업그레이드 (#174) * Hotfix/community (#176) * Fix: 좋아요 반영 안되는 오류 수정 * Fix: response에 wrapping 추가 * Design: 내용 및 사진 누락 추가 * Fix: response wrapping * Design: 디자인 누락 추가 * Refactor: 불필요 로직 삭제 * Feat: 파라미터 명 변경 * Design: 버튼 가려지는 현상 수정 * Fix: hbti 향료개수 자유선택 후 튕기는 현상 수정 * Fix: hbti 향료 선택결과 제출로직 변경 * Fix: hbti 향료선택화면 하단버튼 disabled 상태관리 추가 * Fix: hbti 향료 카테고리 선택화면 로직 변경 반영 * Test: hbti 향료 카테고리 선택화면 로직 변경사항 테스트 * Design: 백버튼 추가 * Feat: 향료 제품 가격 추가 * Refactor: 플래그 제거 및 콜백으로 대체 * Design: 디자인 마진 변경 * Design: Topbar 배경 수정 * Feat: hbti 홈화면 메타데이터 추가 및 기존 데이터 리팩토링 * Design: 홈 디자인 변경 반영 * Design: Topbar 디폴트 배경 변경 * Feat: 로그인 유무 확인 코드 추가 * Design: 스크롤 초기 위치 수정 * Chore: 버전 코드 변경 (24 -> 25) * Design: 향모아 사업자 정보 추가 * Fix: hbti 메타데이터 요청 오류 임시 주석처리 * Chore: 데이터백업설정 변경 * Chore: 테스트 버전 업그레이드 25->27 * chore: gitignore 파일 추가 * chore: 주석해제 * Feat: 상품 구매 여부 확인 다이얼로그 추가 * Feat: Hbti 설문 양옆 스크롤 기능 추가 * Delete: 주석 삭제 * Fix: LazyColumn으로 변경 후 스크롤위치 초기화 적용 * Refactor: isNoteSelectedData상태 업데이트 함수 수정 * fix: Hbti ProgressBar 리컴포지션 최적화 및 UI 버그 개선 * Design: Hbti 향료 선택화면 디테일 변경 * Fix: nullable 처리 누락 수정 * Feat: 향료주문 과정 설명 화면 api 적용 * Feat: 향료주문 과정 설명 화면 네비게이션 추가 * Feat: 가격대 향수추천 결과 화면 추가 * Test: 향수 추천결과 화면 UI/단위 테스트 작성 * Test: 뷰모델 변경사항 반영한 테스트 수정 * Fix: 브랜드 이미지 삭제 반영 * Design: 상단 바 패딩 불일치 수정 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Design: 디자인 추가 수정 * Chore: 버전 코드 수정 27->28 * Design: 버튼 크기 작아지는 현상 수정 * Feature/hbti 디자인 수정 (#185) * Design: 공백 수정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Release 1.0.0(18) 출시 (#147) * Feature-Magazine Init * Chore: Manifest 정리 * Chore: 기본 의존성 설정 * Chore: Test 관련 의존성 정리 * Chore: Compose 설정 * Feat: Response Dto 추가 * Feat: Magazine Screen 추가 * Feat: Magazine Service 추가 * Feat: Magazine Service DI 추가 * Resource: Floating Action Button Open Icon 추가 * Feat: Magazine DataStore 추가 * Fix: Response 타입 수정 * Feat: Data Store DI * Feat: Repository DI * Feat: Magazine Repository 추가 * Feat: 최신 향수 받아오는 API 추가 * Feat: 최신 향수 받아오는 DTO 추가 * Resource: 공유 아이콘 추가 * Feat: Magazine ViewModel 로직 추가 * Design: TopBar 투명도 파라미터 추가 * Rename: 파일 명 변경 * Design: 투명도 추가 * Design: Magazine Tag 추가 * Resource: 아이콘 resource 추가 * Fix: Response 타입 변경 * Chore: Magazine 의존성 추가 * Feat: Magazine Navigation 추가 * Fix: Bottom Navigation 내용 변경 * Feat: Magazine 상세 화면 추가 * Feat: Magazine Paging 추가 * Feat: Magazine Route 클래스 추가 * Feat: Magazine 상세 비즈니스 로직 추가 * Fix: Conflict 수정 * Fix: Paging 오류 수정 * Design: title 색상 파라미터 추가 * Design: title 색상 파라미터 추가 * Design: review content 위치 변경 * Design: Content 글자 수 제한 * Design: title 글자 수 제한 * Fix: 개행문자 수정 * Feat: Navigation 이벤트 추가 * Feat: Magazine 상세 화면 추가 * Feat: Magazine 상세 화면 비즈니스 로직 추가 * Feat: Navigation 이벤트 추가 * Fix: 데이터 순서에 따른 오류 수정 * Design: Tag UI 수정 * Design: Space 크기 조절 * Feat: 좋아요 update 이벤트 추가 * Fix: Navigation 이벤트 파라미터 추가 * Feat: Navigation 이벤트 파라미터 추가 * Design: Magazine UI 위치 수정 * Fix: Magazine Image 추가 * Resource: Magazine Icon 추가 * Design: 바텀 네비게이션 UI 수정 * Feat: Navigation SingleTop 옵션 추가 * Feat: 좋아요 한 향수 페이지 위치 변동 * FIX: 비로그인 에러다이얼로그 동작 오류 수정 * Fix: Navigation 누락 오류 수정 * Fix: err state 누락 오류 수정 * Fix: navigation 누락 수정 * Design: UI 간격 수정 * Gradle: Material 의존성 추가 * Design: 수정 모달 추가 * Refactor: Dialog 팝업 방식 변경 * FIX: 좋아요 리프레싱 시 리컴포지션 안되는 오류 수정 * Rename: 이름 혼동 방지 * Rename: 이름 혼동 방지 * Fix: Dialog Pop up 시 깜빡거림 수정 * Feat: 향수페이지 댓글 오류 수정 * Fix: 향수 페이지 댓글 상태관리 변화 오류 수정 * Delete: 사용하지 않는 상태관리 변수 삭제 * Update README.md * Resource: Font 추가 * Create android.yml develop 브랜치로 코드 푸시, PR 시 빌드되는 기능 * Feat: 자동 빌드 기능 테스트 구문 * Update android.yml * Feat: 자바 버전 11 -> 17 * Fix: CI환경 빌드에 local.properties 파일 동적 생성 기능 추가 * Fix: 경로 오류 수정 * Feat: 모든 모듈의 local-properties파일 삭제 명령파일 생성 * Fix: app 모듈왜 local.properties를 사용하는 모듈도 파일 동적생성 적용 * Chore: 서브 모듈 추가 * Delete: mylibrary 모듈 삭제 * Chore: AndroidSecretSecure 서브 레포지토리 추가 * Revert "Delete: mylibrary 모듈 삭제" This reverts commit cc0c0fd6d21b7f3d941ed11ab515ff2bf6b8e8ab. * Revert "Chore: 서브 모듈 추가" This reverts commit 95cc85845823843a72eb29a6b65a001b99947c6f. * Fix: 소셜 토큰 api 호출 오류 수정 * Ignore * Fix: lateinit 삭제 및 초기화 값 지정 * Fix: IndexOutOfBoundException방지 구문 추가 * Chore: google-service.json 파일 추가 * Rename * Chore: NATIVE_APP_KEY 적용 * Chore: 버전 증가 6->7 * Feat: 토큰 유무 검사 로직 수정 * Feat: 토큰 가져오는 비동기 작업 -> 동기로 변경 * Fix: 토큰 갱신 작업 대기방식을 동기적으로 변경 * Fix: 스트림 닫힘 오류 원인 부분 해결 * Revert "Feat: 토큰 가져오는 비동기 작업 -> 동기로 변경" This reverts commit f56f46f1000603260a6f143dd4304ffc1b4750bf. * Fix: postFcmToken NullPointException 원인구문 삭제 * Fix: 인터셉터 토큰 추가동작 수정 비동기 -> 동기 * Chore: v1.0.0 버전코드 수정 (7->8) * Fix: native app key, string value로 변경 * Fix: HttpLoggingInterceptor 제거 - IllgalStateException 해결을 위해 지워봄 * Refactor: HPediaDesc api호출 분리 및 CastException 해결 * Chore: 버전코드 수정(8->9) * Chore: 버전코드 수정 (9->10) * Fix: 변수 명 오류 * Chore: 버전코드 수정(10->11) * Fix: 카카오 앱 키 참조 방식 변경 * Chore: 버전코드 수정(11->12) * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Chore: core-common 의존성 추가 * Delete: 토큰 재발급 임시 로직 삭제 * HotFix: Authenticator 토큰 재발급 및 에러메세지 전달 기능 수정 * Fix: Authenticator 적용 * Fix: api 호출부에 Authenticator 적용 * Delete: 안쓰는 api 삭제 * Refactor: FCM 초기화 및 초기 라우팅 코드 함수로 분리 * Delete: 임시 refreshToken 코드 관련 api 삭제 * Rename: 토큰 관련 클래스 의존성 주입 모듈 이름 수정 * Fix: 토큰 동적 할당 시점 변경 * Fix: 로그인 화면 이동 네비게이션 변경 * Chore: 버전 변경 (v1.1.1 -> v1.1.2) * Chore: ci,cd 구문 변경 및 action.yml 파일 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: ci/cd 워크플로우 임시로 주석처리 및 사용중지 * Chore: android.yml 워크플로우 일시중지 (#164) * Chore: CI 구문 롤백 및 오작동 CI/CD 임시폴더로 분리 * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 * v1.1.1 버전 master로 머지합니다 (#163) * Feat: Fcm 관련 함수 추가 * Chore: FCM 모듈 의존성 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Chore: fcm 모듈 환경 설정 추가 * Feat: App Navigation 이벤트 추가 * Chore: FCM 모듈 환경 설정 * Resource: 아이콘 추가 * Feat: 알림 수신 여부 이벤트 추가 * Feat: 알림 화면 추가 * Feat: 알림 화면 비즈니스 로직 추가 * Feat: FCM 모듈 추가 * Feat: 알림 Response 모델 추가 * Feat: 알림 화면 네비게이션 추가 * Design: 읽음 여부에 따른 배경색 조절 * Test: 테스트 코드 추가 * Feat: App Scheme 추가 * Feat: Deeplink Navigation 추가 * Ignore * Delete: sample-app 모듈 삭제 * Delete: Hhmoa_android_secret 로컬 폴더 삭제 * Design: Button 컴포넌트 disabled color 이름 적용 * Feat: Hbti설문 아이템 컴포넌트 추가 * Feat: ProgressBar 컴포넌트 생성 * Feat: VerticalStepBar 컴포넌트 생성 * Design: 홈화면 상단 로고 아이콘 추가 * Design: 디자인시스템 모듈 내 컴포넌트에 pretendard 폰트 적용 * Feat: profile 속성 추가 * Feat: send top notification 파라미터 수정 * Feat: profile 속성 추가 * Chore: Activity single top 속성 설정 * Fix: Error Ui State 업데이트 안되는 오류 수정 * Feat: deeplink 처리 함수 추가 * Refactor: Community, HPedia 네비게이션 분리 * Refactor: Community, HPedia 네비게이션 분리 * Feat: deeplink 설정 * Fix: 경로 설정 오류 수정 * Fix: deeplink 위치 오류 수정 * Fix: Response Dto 형식 오류 수정 * Design: Profile 반영 * Feat: 선택 이벤트 추가 * Feat: Navigation 설정 * Feat: 읽음 처리 함수 추가 * Fix: read 변경 가능하도록 수정 * Test: import 수정 * ignore: git pull * Design: 색상 변경 * Feat: NoteImageItem 생성 * Feat: 권한 설정 여부 정보를 확인 * Feat: 권한 설정 함수 추가 * Ignore * Ignore * Feat: feature-hbti 모듈 생성 * Feat:선택지 무효화 기능 추가 및 SurveyOptionList로 수정 * Rename: SurveyOptionItem -> SurveyOptionList * Feat: ProgressBarPreview에 +/- 효과 추가 * Chore: gradle 의존성 추가 * Fix: intent 이름 변경 * Feat: 알림 선택 시 읽음 처리 이벤트 추가 * Feat: 포그라운드 알림 처리 * Fix: Navigation Deeplink 오류 수정 * Chore: mockito 라이브러리 추가 * Feat: HbtiScreen 추가 * Chore: compose material 및 preview 라이브러리 추가 * Feat: Hbti화면 완성 * Design: 향BTI 화면 디자인 구성 완료 * Feat: 향BTI 테스트 데이터계층 클래스 생성 * Rename: SurveyAnswerResponseDto -> SurveyOptionResponseDto * Feat: fcm token 저장 함수 추가 * Fix: 파라미터 이름 오류 수정 * Fix: 토큰 저장 알고리즘 수정 * Feat: 향수 추천 화면 추가 * Design: 공백 수정 * Feat: 데이터 계층 hilt 주입코드 추가 * Feat: HbtiSurvey 화면 추가(미완성) * Feat: 가격 선택 화면 추가 * Design: 아이템 간 간격 조절 * Rename: 컴포넌트 이름 변경 * Rename: 컴포넌트 이름 변경 * Feat: 향료 선택 화면 추가 * Refactor: 화면 구성 변경 * Fix: 파라미터 변경 * Resource: icon 추가 * Fix: 파라미터 수정 * Feat: 향료 선택 화면 추가 * Style: 공백 스타일 변경 * Fix: 푸쉬 오류 수정 * Style: 코드 스타일 변경 * Feat: 향수 추천 결과 화면 추가 * Rename: 컴포넌트 이름 변경 * Ignore * Delete * Chore: test 라이브러리 추가 * Feat: HbtiSurveyViewmodel 생성 * Test: HbtiSurveyViewModel 테스트 생성 * Test: 테스트 기대값 수정 * Feat: Dto 추가 * Feat: Api 추가 * Style: 코드 라인 변경 * Feat: 비즈니스 로직 추가 * Remove: 삭제 * Feat: 향료 데이터 클래스 추가 * Comment: 주석 추가 * Fix: 서버에 정보 전달 로직 임의 대체 * Rename: 함수 명 변경 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: UI 상태 기준 분기 * Feat: Navigation 설정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: android.yml 워크플로우 일시중지 (#164) * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Fix: 파라미터 명시적으로 구분 * Fix: RouteScreen 파라미터 변수명 변경 반영 * Chore: 버전코드 수정 22->23 * Ignore * Fix: 백업데이터 설정 해제 * Chore: 버전 업데이트 * Release 1.1.2버전 master로 푸시 (#167) * Feat: Fcm 관련 함수 추가 * Chore: FCM 모듈 의존성 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Feat: 알림 수신 여부 저장 이벤트 추가 * Chore: fcm 모듈 환경 설정 추가 * Feat: App Navigation 이벤트 추가 * Chore: FCM 모듈 환경 설정 * Resource: 아이콘 추가 * Feat: 알림 수신 여부 이벤트 추가 * Feat: 알림 화면 추가 * Feat: 알림 화면 비즈니스 로직 추가 * Feat: FCM 모듈 추가 * Feat: 알림 Response 모델 추가 * Feat: 알림 화면 네비게이션 추가 * Design: 읽음 여부에 따른 배경색 조절 * Test: 테스트 코드 추가 * Feat: App Scheme 추가 * Feat: Deeplink Navigation 추가 * Ignore * Delete: sample-app 모듈 삭제 * Delete: Hhmoa_android_secret 로컬 폴더 삭제 * Design: Button 컴포넌트 disabled color 이름 적용 * Feat: Hbti설문 아이템 컴포넌트 추가 * Feat: ProgressBar 컴포넌트 생성 * Feat: VerticalStepBar 컴포넌트 생성 * Design: 홈화면 상단 로고 아이콘 추가 * Design: 디자인시스템 모듈 내 컴포넌트에 pretendard 폰트 적용 * Feat: profile 속성 추가 * Feat: send top notification 파라미터 수정 * Feat: profile 속성 추가 * Chore: Activity single top 속성 설정 * Fix: Error Ui State 업데이트 안되는 오류 수정 * Feat: deeplink 처리 함수 추가 * Refactor: Community, HPedia 네비게이션 분리 * Refactor: Community, HPedia 네비게이션 분리 * Feat: deeplink 설정 * Fix: 경로 설정 오류 수정 * Fix: deeplink 위치 오류 수정 * Fix: Response Dto 형식 오류 수정 * Design: Profile 반영 * Feat: 선택 이벤트 추가 * Feat: Navigation 설정 * Feat: 읽음 처리 함수 추가 * Fix: read 변경 가능하도록 수정 * Test: import 수정 * ignore: git pull * Design: 색상 변경 * Feat: NoteImageItem 생성 * Feat: 권한 설정 여부 정보를 확인 * Feat: 권한 설정 함수 추가 * Ignore * Ignore * Feat: feature-hbti 모듈 생성 * Feat:선택지 무효화 기능 추가 및 SurveyOptionList로 수정 * Rename: SurveyOptionItem -> SurveyOptionList * Feat: ProgressBarPreview에 +/- 효과 추가 * Chore: gradle 의존성 추가 * Fix: intent 이름 변경 * Feat: 알림 선택 시 읽음 처리 이벤트 추가 * Feat: 포그라운드 알림 처리 * Fix: Navigation Deeplink 오류 수정 * Chore: mockito 라이브러리 추가 * Feat: HbtiScreen 추가 * Chore: compose material 및 preview 라이브러리 추가 * Feat: Hbti화면 완성 * Design: 향BTI 화면 디자인 구성 완료 * Feat: 향BTI 테스트 데이터계층 클래스 생성 * Rename: SurveyAnswerResponseDto -> SurveyOptionResponseDto * Feat: fcm token 저장 함수 추가 * Fix: 파라미터 이름 오류 수정 * Fix: 토큰 저장 알고리즘 수정 * Feat: 향수 추천 화면 추가 * Design: 공백 수정 * Feat: 데이터 계층 hilt 주입코드 추가 * Feat: HbtiSurvey 화면 추가(미완성) * Feat: 가격 선택 화면 추가 * Design: 아이템 간 간격 조절 * Rename: 컴포넌트 이름 변경 * Rename: 컴포넌트 이름 변경 * Feat: 향료 선택 화면 추가 * Refactor: 화면 구성 변경 * Fix: 파라미터 변경 * Resource: icon 추가 * Fix: 파라미터 수정 * Feat: 향료 선택 화면 추가 * Style: 공백 스타일 변경 * Fix: 푸쉬 오류 수정 * Style: 코드 스타일 변경 * Feat: 향수 추천 결과 화면 추가 * Rename: 컴포넌트 이름 변경 * Ignore * Delete * Chore: test 라이브러리 추가 * Feat: HbtiSurveyViewmodel 생성 * Test: HbtiSurveyViewModel 테스트 생성 * Test: 테스트 기대값 수정 * Feat: Dto 추가 * Feat: Api 추가 * Style: 코드 라인 변경 * Feat: 비즈니스 로직 추가 * Remove: 삭제 * Feat: 향료 데이터 클래스 추가 * Comment: 주석 추가 * Fix: 서버에 정보 전달 로직 임의 대체 * Rename: 함수 명 변경 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: 비즈니스 로직 추가 * Feat: UI 상태 기준 분기 * Feat: Navigation 설정 * Design: On/Off 버튼 디자인 * Test: UI 테스트 * Chore: Firebase 의존성 추가 * Feat: onNewToken 함수 추가 * Feat: 알림 On/Off 알고리즘 추가 * Test: Hbti2 API 테스트 세팅 * Docs: resource 위치 이동 * Chore: 권한 추가 * Remove: 불필요 함수 제거 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Refactor: 파라미터 수정 * Feat: 갤러리 권한 추가 * Refactor: 파라미터 수정 * Style: 공백 제거 * Refactor: 함수 변경 * Fix: 알림 설정 저장 오류 수정 * Feat: 권한 관련 Common 파일 추가 * Fix: Intent Flag 오류 수정 * Fix: 권한 허가 로직 수정 * Fix: Pending Intent 플래그 수정 * Fix: Pending Intent 플래그 수정 * Fix: Conflict * Refactor: 조건 수정 * Style: 공백 정리 * Feat: Error State 추가 * Feat: Error State 추가 * Rename: View Model 이름 변경 * Style: 공백 제거 * Feat: UiState와 ErrorState combine * Fix: 조건 수정 * Feat: Error 상태 관리 추가 * Feat: navigation ci옵션 추가 * Fix: Navigation 변경 * Feat: navigation 스택 제거 함수 추가 * Feat: navigation 스택 조정 * Feat: error state 추가 * Feat: error state 추가 * Feat: error state와 ui state 연결 * Hotfix: Token 오류 수정 * Feat: ErrorUiState 추가 및 유저화면 적용 * Chore: 버전코드 변경 12->13 * Hotfix: 토큰 빈값 방출 수정 * Hotfix: ErrorUiSetView onCloseClick 콜백 동작 수정 및 Rename * Design: 에러메세지 문구 수정 * Chore: 버전코드 수정 13->14 * Feat: 토큰리프레싱 후 기존 토큰 삭제 과정 추가 * Fix: 비동기 처리 완료 후 네비게이팅 하도록 수정 * Hotfix: memberNotFoundError 처리 누락 추가 * Chore: 버전코드 수정 (14->15) * Hotfix: hpedia 커뮤니티 MemberNotFound 상태변수 추가 * Chore: 15->16 버전 코드 수정 * Chore: 버전 코드 수정 16->17 * Hotfix: ErrorState 타입캐스팅 디버깅 구문 삭제 * Chore: 버전코드 수정 (17->18) * Remove: 기능없는 이용약관 삭제 구글 Broken Functionality policy 위반을 피하기 위한 조치입니다! * Delete: 서비스 알림 배너 삭제 * Chore: 패키지명 변경 hmoa -> hyangmoa * Chore: 패키지 명 변경 (hmoa -> hyangmoa) * Chore: 버전코드 1로 초기화 * Revert "Chore: 패키지 명 변경 (hmoa -> hyangmoa)" This reverts commit 811f817ebf54089de05ebabe42bdee964b52d3e1. * Revert "Chore: 버전코드 1로 초기화" This reverts commit 529e65abe5c96a90943b6ffd466ae5a4742570ef. * Revert "Chore: 패키지명 변경 hmoa -> hyangmoa" This reverts commit bfe2d86153421276a831ad4e69dd4ab50dfee72c. * Chore: 테스트 라이브러리 추가 * Test: DataPreference 인풋 아웃풋 비교 테스트 추가 * Chore: 테스트 라이브러리 라이브러리 변경 * Test: DataStorePreference 인풋, 아웃풋 결과값 테스트 * Fix: 토큰이 null일 경우 빈 문자열 처리 * Feat: 이용약관 및 개인정보처리방침 url 수정 * Delete: 주석 삭제 * HotFix: 토큰 빈값 나오는 현상 수정 * HotFix: 토큰 초기화 및 유지 이슈 해결 * Chore: apk 파일 추출 명령어 추가 * Chore: 깃허브 시크릿 카피 스크립트 파일 추가 * Chore: APK 명령어는 master에서만 실행하도록 수정 * Delete: CI환경에 부적합 + 필요없음 * Delete: PR할 때만 CI되도록 수정 * Delete * Delete * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Ignore * Chore: 업데이트 버전명 수정 1.0.0 -> 1.1.0 * Fix: 버전정보 매개변수로 주입하기 추가 * Design: 로그인 버튼 마진 및 구글아이콘 수정 * Design: 향수 검색 화면 마진 수정 * Update README.md * Update README.md * Update README.md * Design: 디자인 디테일 수정 (패딩 및 아이콘 크기) * Design: 아이콘 크기 변경 * Chore: 버전 코드 증가(18->19) * Design: 스위치 on포인트 색상 변경 * Chore: targetSdk 업그레이드 (33 -> 34) * Chore: 버전코드 업데이트 * Chore: action/upload-artifact 버전 변경 * v1.1.1 release로 머지합니다 (#161) * Chore: action/upload-artifact 버전 변경 * Delete: 필요없는 테스트 삭제 * Delete: 불필요 코드 제거 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Feat: 에러핸들링 메서드 추가 * Fix: 에러처리 구문 수정 * Hotfix: 토큰 리프레시 작업 반복구문 추가 * Chore: CI/CD 공통 작업 분리 및 CD 워크플로우 작성 * Feat: 버전 수정 1.1.1(22) * Chore: 프로덕션으로 수정 * Hotfix/hpedia (#160) * Rename: 네비게이션 이벤트 명 변경 * Feat: error state 추가 * Fix: UI state에서 throw를 처리하지 못하는 부분 수정 * Feat: type 설정 변경 * Feat: 변수 관리 조정 및 Error 상태 추가 * Fix: action.yml 추가 (#162) * Chore: v1.1.1 - CD 작업 테스트 * Chore: 환경설정 구문 추가 * Fix: cdWorkflow 파일 수정 환경 설정 구문 삭제 * Fix: ciWorkFlow 파일 수정 환경설정 구문 삭제 * Update whatsnew-ko-KR.txt * Fix: 파일 경로 오타 수정 * Fix: 파일 경로 오타 수정 * Fix: 깃헙 액션 워크플로우 일시 중지 --------- Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Chore: android.yml 워크플로우 일시중지 (#164) * Releasse/1.1.1 CI 구문 롤백 및 새로운 CI/CD 구문 분리 (#165) * Chore: android.yml 워크플로우 일시중지 * Chore: 예전 CI 코드로 rollback 및 새로운 파일 분리 * Chore: actions upload-artifact 라이브러리 버전 업그레이드 * Rename: 이름 변경 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Revert "Chore: 버전 업데이트" This reverts commit 031fc2f141d3ffbc07b0954eda874c58d7e1c834. * Revert "Fix: 백업데이터 설정 해제" This reverts commit bb68a8d265be89d74bcc2feed66baca5355cd475. * HotFix: 카카오 sdk 버전 업그레이드 * HotFix: 카카오 sdk 버전 업그레이드 (#170) * HotFix: 카카오 sdk 버전 업그레이드 * Feat: gradlew clean 작업 추가 * Delete * Delete: refreshToken 추상메서드 삭제 * Delete: 토큰 리프레싱 임시방안 코드 삭제 * HotFix: 카카오 sdk 버전 업그레이드 (#174) * Hotfix/community (#176) * Fix: 좋아요 반영 안되는 오류 수정 * Fix: response에 wrapping 추가 * Design: 내용 및 사진 누락 추가 * Fix: response wrapping * Design: 디자인 누락 추가 * Refactor: 불필요 로직 삭제 * Feat: 파라미터 명 변경 * Design: 버튼 가려지는 현상 수정 * Fix: hbti 향료개수 자유선택 후 튕기는 현상 수정 * Fix: hbti 향료 선택결과 제출로직 변경 * Fix: hbti 향료선택화면 하단버튼 disabled 상태관리 추가 * Fix: hbti 향료 카테고리 선택화면 로직 변경 반영 * Test: hbti 향료 카테고리 선택화면 로직 변경사항 테스트 * Design: 백버튼 추가 * Feat: 향료 제품 가격 추가 * Refactor: 플래그 제거 및 콜백으로 대체 * Design: 디자인 마진 변경 * Design: Topbar 배경 수정 * Feat: hbti 홈화면 메타데이터 추가 및 기존 데이터 리팩토링 * Design: 홈 디자인 변경 반영 * Design: Topbar 디폴트 배경 변경 * Feat: 로그인 유무 확인 코드 추가 * Design: 스크롤 초기 위치 수정 * Chore: 버전 코드 변경 (24 -> 25) * Design: 향모아 사업자 정보 추가 * Fix: hbti 메타데이터 요청 오류 임시 주석처리 * Chore: 데이터백업설정 변경 * Chore: 테스트 버전 업그레이드 25->27 * chore: gitignore 파일 추가 * chore: 주석해제 * Feat: 상품 구매 여부 확인 다이얼로그 추가 * Feat: Hbti 설문 양옆 스크롤 기능 추가 * Delete: 주석 삭제 * Fix: LazyColumn으로 변경 후 스크롤위치 초기화 적용 * Refactor: isNoteSelectedData상태 업데이트 함수 수정 * fix: Hbti ProgressBar 리컴포지션 최적화 및 UI 버그 개선 * Design: Hbti 향료 선택화면 디테일 변경 * Fix: nullable 처리 누락 수정 * Feat: 향료주문 과정 설명 화면 api 적용 * Feat: 향료주문 과정 설명 화면 네비게이션 추가 * Feat: 가격대 향수추천 결과 화면 추가 * Test: 향수 추천결과 화면 UI/단위 테스트 작성 * Test: 뷰모델 변경사항 반영한 테스트 수정 * Fix: 브랜드 이미지 삭제 반영 * Design: 상단 바 패딩 불일치 수정 * Fix: 향수 화면의 브랜드 사진 삭제 반영 * Design: 디자인 추가 수정 * Chore: 버전 코드 수정 27->28 * Design: 버튼 크기 작아지는 현상 수정 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> * Feature/hbti shj 마지막 merge (#186) * Design: 여백 조정 * Rename: 파라미터 명 변경 * Feat: 환불 api 완료 후에 이전 화면으로 navigation 되도록 설정 * Feat: 가격 계산 관련 비즈니스 로직 수정 * Comment: Log 삭제 * Feat: Web Link 연결에서 Web View 사용으로 변경 * Remove: 미사용 UI 삭제 * Feat: 파라미터 타입 변경 (not null >> nullable) * Feat: 파라미터 값 null 여부에 따른 UI 분기 * Rename: navigation route 클래스 위치 이동 (각 feature 모듈 >> core-domain.entity) * Rename: navigation route 클래스 위치 이동 (각 feature 모듈 >> core-domain.entity) * Rename: navigation 이벤트 명 변경 * Rename: navigation 이벤트 명 변경 * Rename: navigation 이벤트 명 변경 * Rename: entity 위치 변경 (각 feature 모듈 & core-model >> core-domain) * Feat: decode from string import 누락 추가 * Feat: decode from string import 누락 추가 * Feat: 주문 내역 조회 paging 처리 * Feat: nullable 처리 * Rename: 파라미터 명 변경 * Chore: 의존성 중복 제거 * Rename: 파라미터 이름 변경 * Fix: 파라미터 변경 * Rename: navigation 이벤트 명 변경 * Rename: 화면 명 변경 * Feat: 환불/반품 내역 조회 api 추가 * Rename: 함수 이름 변경 (getRefund >> getRefundRecord) * Rename: 함수 이름 변경 (getFavoriteCommentPaging >> getOrderRecordPaging) * Rename: 파일 명 변경 (ReturnOrRefundRecordPage >> RefundRecordPage) * Feat: 반품/환불 내역 비즈니스 로직 추가 * Feat: Empty Data Page 컴포넌트 추가 * Feat: view model 연결 * Feat: view model 추가 * Feat: view model 연결 * Fix: 패키지 명 다른 오류 수정 * Remove: 미사용 resource 삭제 * Rename: 디렉토리 명 변경 (Screen >> screen) * Feat: import 문 정리 * Rename: 패키지 명 변경 적용 * Rename: 패키지 명 변경 적용 * Design: padding 조절 * Fix: Response Dto 변경 * Feat: 환불 내역 조회 response 모델 추가 * Feat: response 변경에 따른 createAt 정보 추가 * Feat: navigation 이벤트 추가 * Feat: navigation 이벤트 추가 * Feat: order status 취소 완료 상태 추가 * Feat: order status 반품 완료 상태 추가 * Fix: UI 배송비 누락 수정 * Fix: UI 배송비 누락 수정 * Feat: 반품 완료 상태 추가 * Fix: 배송비 UI 누락 수정 * Design: UI 정렬 * Design: 버튼 삭제 * Remove: 미사용 화면 삭제 * Feat: NoDataPage >> EmptyDataPage 변경 * Design: font 적용 * Remove: 미사용 import 문 제거 * Rename: 파라미터 명 변경 * Feat: 반품 진행 중 상태 추가 * Feat: order status를 기준으로 Button UI 분기 * Feat: 반품 진행 중 상태 추가 * Feat: 리뷰 작성 navigation 이벤트 추가 * Comment: 임의 이벤트 주석 추가 * Rename: 파일 위치 이동 (like 모듈 >> userInfo 모듈) * Rename: navigation 이벤트 명 변경 * Feat: 좋아요 한 향수 화면 route 추가 * Feat: navigation 이벤트 추가 * Remove: like 모듈 삭제 및 user info 모듈 병합 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Rename: navigation 메소드 명 변경 * Ignore: git pull * Test: sort 로직 test * Feat: Paging 내 sort 추가 * Remove: 미사용 resource 삭제 * Fix: 카테고리 내용 변경 (시향기 >> 향BTI 시향기) * Refactor: 변수 위치 변경 * Revert * Ignore: git pull * Ignore: git pull * Feat: 리뷰 컴포넌트 추가 * Feat: 선택 시 사진 확대 추가 * Feat: 선택 시 사진 확대 추가 * Design: 색상 반전 여부 추가 * Feat: int RequestBody형으로 변환 함수 추가 * Chore: decode string 함수 의존성 추가 * Feat: 리뷰 관련 dto 추가 * Feat: photo dto 추가 * Feat: h shop review 관련 api 추가 * Feat: h shop review 관련 api 추가 * Feat: 좋아요 개수 파라미터 추가 * Design: 반전 여부 추가 * Feat: review 화면 추가 * Feat: path 변환 함수 (local uri >> absolute path) * Feat: get my orders api 추가 * Feat: get my orders dto 추가 * Feat: 리뷰 작성 view model 추가 * Feat: 리뷰 작성 화면 view model 연결 * Chore: json decode import 추가 * Feat: 리뷰 작성 navigation 추가 * Fix: FAB 버튼 파라미터 변경 (고정 값 >> 변동 값) * Rename: my orders api 위치 변경 (HShop >> HShopReview) * Feat: 파라미터 타입 변경 (() -> Unit >> Unit) * Feat: navigation 이벤트 추가 * Chore: paging 의존성 추가 * Fix: val >> var * Feat: 선택 가능 여부 설정 파라미터 추가 * Feat: paging 클래스 추가 * Feat: 리뷰 화면 view model 추가 * Feat: 리뷰 화면 view model 연결 * Feat: HBTI 홈 view model 추가 * Design: 테두리 색상 남는 UI 수정 * Design: navigation icon 색상 값 추가 * Style: 코드 스타일 변경 * Feat: navigation 이벤트 추가 * Design: 디자인 파라미터 변경 * Design: 글 색 변경 * Feat: 리뷰 UI 추가 * Design: FAB 디자인 변경 * Design: FAB padding 변경 * Design: icon 색상 변경 * Design: FAB 디자인 변경 * Design: text 변경 * Design: TopBar 색상 변경 * Design: FAB 선택 시 배경 애니메이션 추가 * Design: 컴포넌트 색상 명시 * Feat: 성능 개선을 위한 분리 * Fix: public >> private * Feat: 신고, 삭제 이름 선언 * Feat: 삭제, 신고 이벤트 추가 * Fix: ui 성능 개선 * Remove: 불필요 변수 제거 * Remove: 불필요 변수 제거 * Fix: var >> val * Fix: 좋아요 로직 변경 * Feat: navigation 이벤트 추가 * Chore: material 의존성 추가 * Feat: 좋아요 이벤트 추가 * Feat: 좋아요, 삭제, 신고 기능 추가 * Feat: 수정 api 추가 * Feat: 리뷰 수정 화면 추가 * Feat: 리뷰 수정 비즈니스 로직 추가 * Feat: 리뷰 수정 화면 네비게이션 연결 * Ignore * Design: FAB 버튼 테두리 삭제 * Fix: navigation 이벤트 호출 수정 * Feat: 리뷰 단건 조회, 삭제 api 추가 * Feat: FAB option 변수 값 변경 * Feat: delete review 함수 연결 * Fix: part 어노테이션 네이밍 오류 수정 * Fix: 함수 파라미터 변경 * Fix: 함수 파라미터 변경 * Feat: 삭제 후 ui 반영되도록 flag 추가 * Fix: delay 시간 축소 * Remove: log 삭제 * Design: 아이콘 변경 * Design: 스크롤 범위 전체로 변경 * Feat: 개별 navigation 람다 적용 * Feat: 개별 navigation 람다 적용 * Fix: Part 어노테이션 이름 추가 * Feat: 리뷰 수정 화면 navigation 연결 * Feat: single top 옵션 추가 * Design: 배경 이미지 추가 * Feat: 신고 기능 추가 * Feat: 리뷰 신고 api 추가 * Fix: 파라미터 명 변경 * Style: 코드 줄 변경 * Feat: 이벤트 후 dialog 닫기 * Feat: 작성한 리뷰 navigation 연결 * Rename: getMyOrders api 위치 이동 (hShopReview >> HShop) * Feat: 내가 작성한 review api 추가 * Feat: 내가 작성한 review 화면 추가 * Feat: 내가 작성한 review view model 추가 * Feat: 내 review paging source * Feat: 내 review 화면 연결 * Rename: paging source 위치 이동 * Feat: 리뷰 완료 상태 추가 * Feat: navigation 이벤트 추가 * Feat: createdAt 멤버 변수 추가 * Design: 클릭 범위 변경 * Design: 클릭 범위 변경 * Feat: navigation 파라미터 추가 * Feat: 환불 버튼 클릭 시 dialog 생성 * Design: fontSize, lineHeight 조정 * Design: 날짜 추가, 색상 변경 * Remove: 미사용 dto 삭제 * Fix: OrderStatus에 리뷰 완료 상태 >> isReviewed 멤버 변수로 변경 * Design: review 작성 여부와 order status에 따른 UI 변경 * Design: review 작성 여부와 order status에 따른 UI 변경 * Feat: navigation 이벤트 추가 * Design: 텍스트 문구 변경 * Fix: navigation 경로 수정 * Fix: review 사용 조건 변경 * Design: top bar 배경 색상 변경 * Refactor: 중복 함수 제거 * Fix: 닉네임 중복 확인 api 변경 반영 * Remove: 불필요 파라미터 제거 * Refactor: Recomposition 줄도록 수정 * Fix: 느린 상태 update 수정 * Fix: 느린 상태 update 수정 * Refactor: recomposition 감소 유도 * Ignore: Merge * Design: top bar 색상 추가 * Fix: 배송 요청을 선택 사항으로 변경 * Design: 단일 매거진 Pager로 변경 * Feat: ResultResponse Wrapping * Feat: nav login 네비게이션 이벤트 추가 * Refactor: Recomposition 감소 * Refactor: Recomposition 감소 * Feat: authenticator 추가 * Feat: authenticator 추가 * Style: 여백 삭제 * Design: 테두리 추가 * Refactor: Recomposition 감소 * Rename: 파라미터 명 변경 * Refactor: Recomposition 감소 * Refactor: Recomposition 감소 * Fix: NullPointerException 오류 수정 * Design: 버튼 색상 변경 * Design: 뒤고 가기 버튼 삭제 * Feat: navigation 도착지 변경 (홈 >> Hbti 홈) * Feat: navigation stack 정리 * Feat: navigation stack 정리 * Fix: Nickname Input 컴포넌트 파라미터 변경에 따른 수정 * Style: 중복 호출부 제거 * Refactor: Recomposition 감소 * Refactor: Recomposition 감소 * Refactor: LazyColumn 최적화 * Comment: 화면 내용 관련 주석 추가 * Design: text 추가 * Design: text 추가 * Fix: is enable 조건 변경 * Design: 글자 색상 변경 * Refactor: Recomposition 감소 * Ignore: git pull * Design: 안내 문구 추가 * Design: weight 수정 * Fix: 조건 수정 * Fix: 조건 수정 * Fix: buyer info 업데이트 안되느 오류 수정 * Chore: 버전코드 변경 28->30 * Design: 향수 이미지 패딩 추가 * Chore: 버전코드 변경 30->31 * HotFix: nullable 처리 속성 추가 * Chore: 1.2.0 버전으로 업데이트 표기 변경 --------- Co-authored-by: uselessNaming Co-authored-by: Seo Hojun <101941674+uselessnaming@users.noreply.github.com> --- .github/workflows/android.yml | 8 +- .gitignore | 2 + .idea/androidTestResultsUserPreferences.xml | 104 ++ .idea/deploymentTargetSelector.xml | 4 +- .idea/git_toolbox_blame.xml | 6 + .idea/gradle.xml | 1 - .idea/other.xml | 22 +- app/build.gradle.kts | 26 +- app/src/main/AndroidManifest.xml | 5 +- .../main/java/com/hmoa/app/MainActivity.kt | 95 +- .../java/com/hmoa/app/navigation/NavHost.kt | 129 ++- copy-hmoa-android-secrets.sh | 2 + core-common/build.gradle.kts | 1 + .../com/hmoa/core_common/CommonFunctions.kt | 72 ++ .../java/com/hmoa/core_common/ErrorUiState.kt | 6 +- core-database/build.gradle.kts | 2 + .../hmoa/core_database/di}/DatabaseModule.kt | 2 +- .../LocalDataStorePreferenceManagerModule.kt | 17 +- .../hmoa/core_database/lrucache/CacheKey.kt | 6 + .../lrucache/PerfumeRecommendCacheManager.kt | 11 + .../PerfumeRecommendCacheManagerImpl.kt | 26 + .../Bootpay/BootpayDataStore.kt | 13 + .../Bootpay/BootpayDataStoreImpl.kt | 66 ++ .../Community/CommunityDataStore.kt | 1 - .../hmoa/core_datastore/DatastoreModule.kt | 12 + .../HShopReview/HShopReviewDataStore.kt | 26 + .../HShopReview/HShopReviewDataStoreImpl.kt | 117 +++ .../Hshop/HshopRemoteDataStore.kt | 12 +- .../Hshop/HshopRemoteDataStoreImpl.kt | 88 +- .../Mapper/IntToMultipartBody.kt | 4 + .../core_datastore/Member/MemberDataStore.kt | 15 +- .../Member/MemberDataStoreImpl.kt | 152 ++- .../core_datastore/Report/ReportDataStore.kt | 7 +- .../Report/ReportDataStoreImpl.kt | 47 +- .../Survey/SurveyLocalDataStore.kt | 8 +- .../Survey/SurveyLocalDataStoreImpl.kt | 34 +- .../Survey/SurveyRemoteDataStore.kt | 20 +- .../Survey/SurveyRemoteDataStoreImpl.kt | 62 +- core-designsystem/build.gradle.kts | 1 + .../component/AppDesignDialog.kt | 24 +- .../component/BottomCameraBtn.kt | 25 +- .../core_designsystem/component/Button.kt | 9 +- .../core_designsystem/component/Comment.kt | 23 +- .../component/CustomOutlinedTextField.kt | 75 ++ .../component/EmptyDataPage.kt | 42 + .../component/FloatingActionBtn.kt | 121 ++- .../component/HmoaLogoLoading.kt | 55 + .../core_designsystem/component/HomeTopBar.kt | 139 ++- .../component/LikeRowlistItem.kt | 169 +-- .../component/MainBottomBar.kt | 96 +- .../component/NicknameInput.kt | 102 +- .../component/NoteImageItem.kt | 12 + .../component/NoteListItem.kt | 113 ++ .../component/NoteSelectedDescription.kt | 130 +++ .../component/OrderHistoryItem.kt | 376 +++++++ .../component/PerfumeItemView.kt | 18 +- .../component/PerfumeWithCountItemView.kt | 13 +- .../component/PostContent.kt | 82 +- .../component/PostListItem.kt | 83 +- .../component/ProgressBar.kt | 11 +- .../core_designsystem/component/ReviewItem.kt | 285 +++++ .../core_designsystem/component/Spinner.kt | 2 +- .../component/SurveyOptionList.kt | 66 +- .../core_designsystem/component/TagBadge.kt | 17 +- .../core_designsystem/component/TopBar.kt | 45 +- .../core_designsystem/component/TypeBadge.kt | 2 +- .../component/VerticalStepBar.kt | 15 +- .../component/YearPickerDialog.kt | 2 +- .../core_designsystem/theme/CustomFont.kt | 17 + .../src/main/res/drawable/hmoa.gif | Bin 0 -> 11058067 bytes .../drawable/ic_check_not_have_background.xml | 13 + .../drawable/ic_vertical_three_dot_menu.xml | 15 + .../com/hmoa/core_domain/entity}/data/Age.kt | 2 +- .../entity/data}/AllPerfumeScreenId.kt | 2 +- .../core_domain/entity/data}/ColumnData.kt | 2 +- .../core_domain/entity}/data/Consonant.kt | 2 +- .../entity/data/HbtiQuestionItem.kt | 10 + .../entity/data/HbtiQuestionItems.kt | 8 + .../core_domain/entity}/data/HpediaType.kt | 2 +- .../entity}/data/MagazineContentItem.kt | 2 +- .../entity}/data/MagazineSuccessItem.kt | 2 +- .../entity/data}/MyPageCategory.kt | 2 +- .../entity/data/NoteOrderQuantity.kt | 5 + .../core_domain/entity/data/NoteSelect.kt | 8 + .../hmoa/core_domain/entity}/data/Perfume.kt | 3 +- .../core_domain/entity/data}/PerfumeGender.kt | 2 +- .../entity/data}/PerfumeSearchViewType.kt | 2 +- .../hmoa/core_domain/entity}/data/SortType.kt | 2 +- .../hmoa/core_domain/entity}/data/Spice.kt | 2 +- .../hmoa/core_domain/entity}/data/UserInfo.kt | 2 +- .../hmoa/core_domain/entity/data}/Weather.kt | 2 +- .../core_domain/entity/data/WebviewType.kt | 6 + .../entity}/navigation/AuthenticationRoute.kt | 2 +- .../entity}/navigation/BrandRoute.kt | 2 +- .../entity/navigation}/CommunityRoute.kt | 2 +- .../entity/navigation}/HPediaRoute.kt | 2 +- .../entity/navigation/HbtiRoute.kt | 19 + .../entity}/navigation/HomeRoute.kt | 2 +- .../entity/navigation}/MagazineRoute.kt | 2 +- .../entity}/navigation/PerfumeRoute.kt | 2 +- .../entity/navigation/UserInfoRoute.kt | 9 +- .../repository/BootpayRepository.kt | 13 + .../repository/HShopReviewRepository.kt | 26 + .../core_domain/repository/HshopRepository.kt | 12 +- .../repository/MemberRepository.kt | 15 +- .../repository/ReportRepository.kt | 7 +- .../repository/SurveyRepository.kt | 18 +- ...lculateMinAndMaxPriceOutOfStringUseCase.kt | 27 + .../CheckNicknameDuplicationUseCase.kt | 11 - .../usecase/GetMagazineDescription.kt | 4 +- .../usecase/GetMyUserInfoUseCase.kt | 2 +- .../core_domain/usecase/GetNicknameUseCase.kt | 11 - .../usecase/GetPerfumeSurveyUseCase.kt | 34 + .../core_domain/usecase/GetPerfumeUsecase.kt | 5 +- .../usecase/SaveGoogleTokenUseCase.kt | 8 - .../usecase/SaveKakaoTokenUseCase.kt | 10 - .../usecase/SaveSignupInfoUseCase.kt | 14 - .../usecase/UpdatePerfumeAgeUseCase.kt | 2 +- .../usecase/UpdatePerfumeGenderUseCase.kt | 2 +- .../usecase/UpdatePerfumeWeatherUseCase.kt | 2 +- .../hmoa/core_model/PerfumeRecommendType.kt | 5 + .../hmoa/core_model/data/DefaultAddressDto.kt | 15 + .../core_model/data/DefaultOrderInfoDto.kt | 6 + .../hmoa/core_model/data/NoteProductIds.kt | 8 + .../com/hmoa/core_model/data/OrderStatus.kt | 13 + .../core_model/data/PerfumeSurveyContents.kt | 16 + .../request/CancelBootpayRequestDto.kt | 9 + .../request/ConfirmBootpayRequestDto.kt | 8 + .../request/PerfumeSurveyAnswerRequestDto.kt | 10 + .../core_model/response/BootpayMetaData.kt | 6 + .../response/BootpayOrderResultData.kt | 30 + .../core_model/response/BootpayResponseDto.kt | 10 + .../response/BrandDefaultResponseDto.kt | 2 - .../com/hmoa/core_model/response/CardData.kt | 15 + .../response/ContentAndTitleResponse.kt | 9 + .../response/FinalOrderResponseDto.kt | 11 + .../response/GetMyOrderResponseDto.kt | 9 + .../response/GetRefundRecordResponseDto.kt | 14 + .../response/HbtiHomeMetaDataResponse.kt | 11 + .../core_model/response/MemberAddressDto.kt | 15 + .../response/MemberSimpleInfoDto.kt | 9 + .../java/com/hmoa/core_model/response/Note.kt | 9 + .../hmoa/core_model/response/NoteProduct.kt | 13 + .../core_model/response/NoteQuestionDto.kt | 9 + .../response/NotesAndCategoryDto.kt | 9 + .../response/OrderDescriptionResponseDto.kt | 9 + .../core_model/response/OrderRecordDto.kt | 15 + .../response/PerfumeDetailResponseDto.kt | 1 - .../response/PerfumeRecommendResponseDto.kt | 13 + .../response/PerfumeRecommendsResponseDto.kt | 8 + .../response/PerfumeSurveyResponseDto.kt | 9 + .../com/hmoa/core_model/response/Photo.kt | 9 + .../response/PostNoteOrderResponseDto.kt | 11 + .../response/PostNoteSelectedResponseDto.kt | 9 + .../core_model/response/ProductResponseDto.kt | 3 +- .../response/RecentPerfumeResponseDtoItem.kt | 7 +- .../core_model/response/ReviewResponseDto.kt | 18 + .../response/SurveyQuestionResponseDto.kt | 1 + .../com/hmoa/core_network/di/ServiceModule.kt | 12 + .../core_network/service/BootpayService.kt | 28 + .../service/HShopReviewService.kt | 53 + .../hmoa/core_network/service/HshopService.kt | 34 +- .../core_network/service/MemberService.kt | 49 +- .../core_network/service/ReportService.kt | 9 +- .../core_network/service/SurveyService.kt | 38 +- .../core_repository/BootpayRepositoryImpl.kt | 26 + .../HShopReviewRepositoryImpl.kt | 52 + .../core_repository/HshopRepositoryImpl.kt | 35 +- .../core_repository/MemberRepositoryImpl.kt | 33 +- .../core_repository/ReportRepositoryImpl.kt | 9 +- .../hmoa/core_repository/RepositoryModule.kt | 8 + .../core_repository/SurveyRepositoryImpl.kt | 35 +- .../PickNicknameScreen.kt | 129 ++- .../PickPersonalInfoScreen.kt | 6 +- .../navigation/AuthenticationNavigation.kt | 1 + .../viewmodel/PickNicknameViewmodel.kt | 52 +- .../viewmodel/PickPersonalInfoViewmodel.kt | 6 +- .../navigation/BrandNavigation.kt | 1 + .../hmoa/feature_brand/screen/BrandScreen.kt | 62 +- .../feature_brand/screen/BrandSearchScreen.kt | 66 +- .../viewmodel/BrandSearchViewmodel.kt | 2 +- .../feature_brand/viewmodel/BrandViewmodel.kt | 2 +- .../feature_community/Navigation/NavGraph.kt | 21 +- .../Screen/CommunityDescriptionPage.kt | 179 ++-- .../Screen/CommunityEditPage.kt | 59 +- .../feature_community/Screen/CommunityHome.kt | 31 +- .../Screen/CommunityPostPage.kt | 139 +-- .../Screen/CommunityPreview.kt | 125 ++- .../ViewModel/CommunityDescViewModel.kt | 184 ++-- ...ViewModel.kt => CommunityMainViewModel.kt} | 28 +- .../ViewModel/CommunityPostViewModel.kt | 81 +- .../res/drawable/ic_launcher_background.xml | 170 --- .../res/drawable/ic_launcher_foreground.xml | 30 - .../res/mipmap-anydpi-v26/ic_launcher.xml | 6 - .../mipmap-anydpi-v26/ic_launcher_round.xml | 6 - .../src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 1404 -> 0 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 2898 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 982 -> 0 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 1772 -> 0 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 1900 -> 0 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 3918 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 2884 -> 0 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 5914 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 3844 -> 0 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 7778 -> 0 bytes .../src/main/res/values-night/themes.xml | 16 - .../src/main/res/values/colors.xml | 10 - .../src/main/res/values/strings.xml | 3 - .../src/main/res/values/themes.xml | 16 - feature-fcm/build.gradle.kts | 1 - .../java/com/hmoa/feature_fcm/AlarmScreen.kt | 50 +- .../com/hmoa/feature_fcm/AlarmViewModel.kt | 16 +- feature-hbti/build.gradle.kts | 44 +- .../feature_hbti/ExampleInstrumentedTest.kt | 24 - .../HbtiSurveyResultScreenTest.kt | 81 ++ .../hmoa/feature_hbti/HbtiSurveyScreenTest.kt | 100 ++ .../hmoa/feature_hbti/NotePickScreenTest.kt | 122 +++ .../PerfumeRecommendationResultScreenTest.kt | 30 + .../feature_hbti/navigation/HbtiNavigation.kt | 265 ++++- .../hmoa/feature_hbti/navigation/HbtiRoute.kt | 5 - .../feature_hbti/paging/ReviewPagingSource.kt | 35 + .../feature_hbti/screen/AddAddressScreen.kt | 759 ++++++++++++++ .../screen/DeletableTagBadgeScroller.kt | 101 ++ .../feature_hbti/screen/EditReviewScreen.kt | 291 ++++++ .../feature_hbti/screen/HbtiProcessScreen.kt | 141 ++- .../hmoa/feature_hbti/screen/HbtiScreen.kt | 616 +++++++---- .../screen/HbtiSurveyLoadingScreen.kt | 71 ++ .../screen/HbtiSurveyResultScreen.kt | 237 ++--- .../feature_hbti/screen/HbtiSurveyScreen.kt | 267 ++--- .../screen/NoteOrderQuantityPickScreen.kt | 129 ++- .../screen/NotePickResultScreen.kt | 236 +++++ .../feature_hbti/screen/NotePickScreen.kt | 177 +++- .../feature_hbti/screen/OrderResultScreen.kt | 70 ++ .../hmoa/feature_hbti/screen/OrderScreen.kt | 988 ++++++++++++++++++ .../PerfumeRecommendationResultScreen.kt | 262 +++-- .../screen/PerfumeRecommendationScreen.kt | 413 ++++++-- .../hmoa/feature_hbti/screen/ReviewScreen.kt | 312 ++++++ .../feature_hbti/screen/SelectSpiceScreen.kt | 292 ------ .../feature_hbti/screen/WriteReviewScreen.kt | 261 +++++ .../viewmodel/AddAddressViewModel.kt | 75 ++ .../viewmodel/EditReviewViewModel.kt | 140 +++ .../viewmodel/HbtiHomeViewModel.kt | 232 ++++ .../viewmodel/HbtiProcessViewmodel.kt | 104 ++ .../viewmodel/HbtiSurveyLoadingViewmodel.kt | 73 ++ .../viewmodel/HbtiSurveyResultViewmodel.kt | 34 +- .../viewmodel/HbtiSurveyViewmodel.kt | 357 ++++--- .../NoteOrderQuantityPickViewmodel.kt | 54 +- .../viewmodel/NotePickResultViewModel.kt | 81 ++ .../viewmodel/NotePickViewmodel.kt | 234 +++-- .../feature_hbti/viewmodel/OrderViewModel.kt | 328 ++++++ .../PerfumeRecommendationResultViewModel.kt | 86 +- .../PerfumeRecommendationViewModel.kt | 317 +++++- .../feature_hbti/viewmodel/ReviewViewModel.kt | 156 +++ .../viewmodel/WriteReviewViewModel.kt | 78 ++ .../feature_hbti/HbtiSurveyViewModelTest.kt | 349 +++++++ .../NoteOrderQuantityPickViewmodelTest.kt | 86 ++ .../feature_hbti/NotePickViewmodelTest.kt | 323 ++++++ ...erfumeRecommendationResultViewmodelTest.kt | 74 ++ .../PerfumeRecommendationViewmodelTest.kt | 282 +++++ .../hmoa/feature_hbti/TestCoroutineRule.kt | 25 + .../feature_home/navigation/HomeNavigation.kt | 14 +- .../feature_home/screen/AllPerfumeScreen.kt | 4 +- .../hmoa/feature_home/screen/HomeScreen.kt | 294 ++++-- .../screen/PerfumeSearchScreen.kt | 2 +- .../viewmodel/AllPerfumeViewModel.kt | 2 +- .../feature_home/viewmodel/HomeViewModel.kt | 12 +- .../viewmodel/PerfumeSearchViewmodel.kt | 5 +- .../feature_hpedia/Navigation/NavGraph.kt | 20 +- .../feature_hpedia/Screen/HPediaDescScreen.kt | 4 +- .../feature_hpedia/Screen/HPediaScreen.kt | 12 +- .../Screen/HpediaSearchScreen.kt | 16 +- .../ViewModel/HPediaDescViewModel.kt | 2 +- feature-like/.gitignore | 1 - feature-like/build.gradle.kts | 82 -- feature-like/proguard-rules.pro | 21 - .../feature_like/ExampleInstrumentedTest.kt | 24 - feature-like/src/main/AndroidManifest.xml | 3 - .../Screen/NoSavePerfumeScreen.kt | 63 -- .../feature_like/ViewModel/LikeViewModel.kt | 106 -- .../res/drawable/ic_launcher_background.xml | 170 --- .../res/drawable/ic_launcher_foreground.xml | 30 - .../example/feature_like/ExampleUnitTest.kt | 17 - feature-magazine/build.gradle.kts | 2 +- .../Navigation/MagazineNavigation.kt | 13 +- .../feature_magazine/Screen/MagazineDesc.kt | 215 ++-- .../feature_magazine/Screen/MagazineMain.kt | 271 +++-- .../ViewModel/MagazineDescViewModel.kt | 2 +- .../navigation/perfumeNavigation.kt | 20 +- .../screen/PerfumeCommentScreen.kt | 4 +- .../feature_perfume/screen/PerfumeScreen.kt | 105 +- .../screen/SpecificCommentScreen.kt | 2 +- .../viewmodel/PerfumeCommentViewmodel.kt | 2 +- .../viewmodel/PerfumeViewmodel.kt | 6 +- feature-userInfo/build.gradle.kts | 1 - .../Screen/EditProfilePage.kt | 160 ++- .../feature_userinfo/Screen/MyActivityPage.kt | 72 +- .../feature_userinfo/Screen/MyBirthPage.kt | 139 ++- .../feature_userinfo/Screen/MyCommentPage.kt | 126 ++- .../Screen/MyFavoriteCommentPage.kt | 99 +- .../Screen/MyFavoritePrefumePage.kt | 166 +-- .../feature_userinfo/Screen/MyGenderPage.kt | 70 +- .../feature_userinfo/Screen/MyInfoPage.kt | 62 +- .../hmoa/feature_userinfo/Screen/MyPage.kt | 297 +++--- .../feature_userinfo/Screen/MyPostPage.kt | 57 +- .../hmoa/feature_userinfo/Screen/MyReview.kt | 135 +++ .../feature_userinfo/Screen/NoAuthMyPage.kt | 10 +- .../feature_userinfo/Screen/NoDataPage.kt | 55 - .../Screen/OrderRecordPage.kt | 148 +++ .../feature_userinfo/Screen/RefundPage.kt | 301 ++++++ .../Screen/RefundRecordPage.kt | 186 ++++ .../feature_userinfo/navigation/NavGraph.kt | 202 ++-- .../{ => paging}/CommentPagingSource.kt | 2 +- .../{ => paging}/CommunityPagingSource.kt | 2 +- .../FavoriteCommentPagingSource.kt | 2 +- .../paging/OrderPagingSource.kt | 40 + .../paging/RefundRecordPagingSource.kt | 55 + .../paging/ReviewPagingSource.kt | 39 + .../viewModel/CommentViewModel.kt | 11 +- .../viewModel/EditProfileViewModel.kt | 202 ++-- .../viewModel/FavoriteCommentViewModel.kt | 27 +- .../viewModel/MyBirthViewModel.kt | 57 +- .../viewModel/MyFavoritePerfumeViewModel.kt | 81 ++ .../viewModel/MyGenderViewModel.kt | 58 +- .../viewModel/MyPageViewModel.kt | 89 +- .../viewModel/MyReviewViewModel.kt | 72 ++ .../viewModel/OrderRecordViewModel.kt | 99 ++ .../viewModel/PostViewModel.kt | 14 +- .../viewModel/RefundRecordViewModel.kt | 99 ++ .../viewModel/RefundViewModel.kt | 110 ++ .../hmoa/feature_userinfo/ExampleUnitTest.kt | 173 +++ load-env-from-json.sh | 42 - ...erties.sh => reset-hmoa-android-secrets.sh | 2 + settings.gradle.kts | 1 - setup-local-properties.sh | 2 + 334 files changed, 15942 insertions(+), 5051 deletions(-) create mode 100644 .idea/git_toolbox_blame.xml create mode 100644 core-common/src/main/java/com/hmoa/core_common/CommonFunctions.kt rename {core-datastore/src/main/java/com/hmoa/core_datastore => core-database/src/main/java/com/hmoa/core_database/di}/DatabaseModule.kt (95%) rename {core-datastore/src/main/java/com/hmoa/core_datastore => core-database/src/main/java/com/hmoa/core_database/di}/LocalDataStorePreferenceManagerModule.kt (58%) create mode 100644 core-database/src/main/java/com/hmoa/core_database/lrucache/CacheKey.kt create mode 100644 core-database/src/main/java/com/hmoa/core_database/lrucache/PerfumeRecommendCacheManager.kt create mode 100644 core-database/src/main/java/com/hmoa/core_database/lrucache/PerfumeRecommendCacheManagerImpl.kt create mode 100644 core-datastore/src/main/java/com/hmoa/core_datastore/Bootpay/BootpayDataStore.kt create mode 100644 core-datastore/src/main/java/com/hmoa/core_datastore/Bootpay/BootpayDataStoreImpl.kt create mode 100644 core-datastore/src/main/java/com/hmoa/core_datastore/HShopReview/HShopReviewDataStore.kt create mode 100644 core-datastore/src/main/java/com/hmoa/core_datastore/HShopReview/HShopReviewDataStoreImpl.kt create mode 100644 core-designsystem/src/main/java/com/hmoa/core_designsystem/component/CustomOutlinedTextField.kt create mode 100644 core-designsystem/src/main/java/com/hmoa/core_designsystem/component/EmptyDataPage.kt create mode 100644 core-designsystem/src/main/java/com/hmoa/core_designsystem/component/HmoaLogoLoading.kt create mode 100644 core-designsystem/src/main/java/com/hmoa/core_designsystem/component/NoteListItem.kt create mode 100644 core-designsystem/src/main/java/com/hmoa/core_designsystem/component/NoteSelectedDescription.kt create mode 100644 core-designsystem/src/main/java/com/hmoa/core_designsystem/component/OrderHistoryItem.kt create mode 100644 core-designsystem/src/main/java/com/hmoa/core_designsystem/component/ReviewItem.kt create mode 100644 core-designsystem/src/main/java/com/hmoa/core_designsystem/theme/CustomFont.kt create mode 100644 core-designsystem/src/main/res/drawable/hmoa.gif create mode 100644 core-designsystem/src/main/res/drawable/ic_check_not_have_background.xml create mode 100644 core-designsystem/src/main/res/drawable/ic_vertical_three_dot_menu.xml rename {core-model/src/main/java/com/hmoa/core_model => core-domain/src/main/java/com/hmoa/core_domain/entity}/data/Age.kt (69%) rename {feature-home/src/main/java/com/hmoa/feature_home => core-domain/src/main/java/com/hmoa/core_domain/entity/data}/AllPerfumeScreenId.kt (59%) rename {feature-userInfo/src/main/java/com/hmoa/feature_userinfo => core-domain/src/main/java/com/hmoa/core_domain/entity/data}/ColumnData.kt (66%) rename {core-model/src/main/java/com/hmoa/core_model => core-domain/src/main/java/com/hmoa/core_domain/entity}/data/Consonant.kt (87%) create mode 100644 core-domain/src/main/java/com/hmoa/core_domain/entity/data/HbtiQuestionItem.kt create mode 100644 core-domain/src/main/java/com/hmoa/core_domain/entity/data/HbtiQuestionItems.kt rename {core-model/src/main/java/com/hmoa/core_model => core-domain/src/main/java/com/hmoa/core_domain/entity}/data/HpediaType.kt (70%) rename {core-model/src/main/java/com/hmoa/core_model => core-domain/src/main/java/com/hmoa/core_domain/entity}/data/MagazineContentItem.kt (76%) rename {core-model/src/main/java/com/hmoa/core_model => core-domain/src/main/java/com/hmoa/core_domain/entity}/data/MagazineSuccessItem.kt (87%) rename {feature-userInfo/src/main/java/com/hmoa/feature_userinfo => core-domain/src/main/java/com/hmoa/core_domain/entity/data}/MyPageCategory.kt (57%) create mode 100644 core-domain/src/main/java/com/hmoa/core_domain/entity/data/NoteOrderQuantity.kt create mode 100644 core-domain/src/main/java/com/hmoa/core_domain/entity/data/NoteSelect.kt rename {core-model/src/main/java/com/hmoa/core_model => core-domain/src/main/java/com/hmoa/core_domain/entity}/data/Perfume.kt (93%) rename {core-model/src/main/java/com/hmoa/core_model => core-domain/src/main/java/com/hmoa/core_domain/entity/data}/PerfumeGender.kt (57%) rename {feature-home/src/main/java/com/hmoa/feature_home => core-domain/src/main/java/com/hmoa/core_domain/entity/data}/PerfumeSearchViewType.kt (55%) rename {core-model/src/main/java/com/hmoa/core_model => core-domain/src/main/java/com/hmoa/core_domain/entity}/data/SortType.kt (50%) rename {core-model/src/main/java/com/hmoa/core_model => core-domain/src/main/java/com/hmoa/core_domain/entity}/data/Spice.kt (66%) rename {core-model/src/main/java/com/hmoa/core_model => core-domain/src/main/java/com/hmoa/core_domain/entity}/data/UserInfo.kt (77%) rename {core-model/src/main/java/com/hmoa/core_model => core-domain/src/main/java/com/hmoa/core_domain/entity/data}/Weather.kt (58%) create mode 100644 core-domain/src/main/java/com/hmoa/core_domain/entity/data/WebviewType.kt rename {feature-authentication/src/main/java/com/hmoa/feature_authentication => core-domain/src/main/java/com/hmoa/core_domain/entity}/navigation/AuthenticationRoute.kt (65%) rename {feature-brand/src/main/java/com/hmoa/feature_brand => core-domain/src/main/java/com/hmoa/core_domain/entity}/navigation/BrandRoute.kt (53%) rename {feature-community/src/main/java/com/hmoa/feature_community/Navigation => core-domain/src/main/java/com/hmoa/core_domain/entity/navigation}/CommunityRoute.kt (83%) rename {feature-hpedia/src/main/java/com/hmoa/feature_hpedia/Navigation => core-domain/src/main/java/com/hmoa/core_domain/entity/navigation}/HPediaRoute.kt (68%) create mode 100644 core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/HbtiRoute.kt rename {feature-home/src/main/java/com/hmoa/feature_home => core-domain/src/main/java/com/hmoa/core_domain/entity}/navigation/HomeRoute.kt (59%) rename {feature-magazine/src/main/java/com/hmoa/feature_magazine/Navigation => core-domain/src/main/java/com/hmoa/core_domain/entity/navigation}/MagazineRoute.kt (58%) rename {feature-perfume/src/main/java/com/hmoa/feature_perfume => core-domain/src/main/java/com/hmoa/core_domain/entity}/navigation/PerfumeRoute.kt (75%) rename feature-userInfo/src/main/java/com/hmoa/feature_userinfo/navigation/UserInfoGraph.kt => core-domain/src/main/java/com/hmoa/core_domain/entity/navigation/UserInfoRoute.kt (61%) create mode 100644 core-domain/src/main/java/com/hmoa/core_domain/repository/BootpayRepository.kt create mode 100644 core-domain/src/main/java/com/hmoa/core_domain/repository/HShopReviewRepository.kt create mode 100644 core-domain/src/main/java/com/hmoa/core_domain/usecase/CalculateMinAndMaxPriceOutOfStringUseCase.kt delete mode 100644 core-domain/src/main/java/com/hmoa/core_domain/usecase/CheckNicknameDuplicationUseCase.kt delete mode 100644 core-domain/src/main/java/com/hmoa/core_domain/usecase/GetNicknameUseCase.kt create mode 100644 core-domain/src/main/java/com/hmoa/core_domain/usecase/GetPerfumeSurveyUseCase.kt delete mode 100644 core-domain/src/main/java/com/hmoa/core_domain/usecase/SaveGoogleTokenUseCase.kt delete mode 100644 core-domain/src/main/java/com/hmoa/core_domain/usecase/SaveKakaoTokenUseCase.kt delete mode 100644 core-domain/src/main/java/com/hmoa/core_domain/usecase/SaveSignupInfoUseCase.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/PerfumeRecommendType.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/data/DefaultAddressDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/data/DefaultOrderInfoDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/data/NoteProductIds.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/data/OrderStatus.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/data/PerfumeSurveyContents.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/request/CancelBootpayRequestDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/request/ConfirmBootpayRequestDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/request/PerfumeSurveyAnswerRequestDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/BootpayMetaData.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/BootpayOrderResultData.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/BootpayResponseDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/CardData.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/ContentAndTitleResponse.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/FinalOrderResponseDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/GetMyOrderResponseDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/GetRefundRecordResponseDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/HbtiHomeMetaDataResponse.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/MemberAddressDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/MemberSimpleInfoDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/Note.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/NoteProduct.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/NoteQuestionDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/NotesAndCategoryDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/OrderDescriptionResponseDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/OrderRecordDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/PerfumeRecommendResponseDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/PerfumeRecommendsResponseDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/PerfumeSurveyResponseDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/Photo.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/PostNoteOrderResponseDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/PostNoteSelectedResponseDto.kt create mode 100644 core-model/src/main/java/com/hmoa/core_model/response/ReviewResponseDto.kt create mode 100644 core-network/src/main/java/com/hmoa/core_network/service/BootpayService.kt create mode 100644 core-network/src/main/java/com/hmoa/core_network/service/HShopReviewService.kt create mode 100644 core-repository/src/main/java/com/hmoa/core_repository/BootpayRepositoryImpl.kt create mode 100644 core-repository/src/main/java/com/hmoa/core_repository/HShopReviewRepositoryImpl.kt rename feature-community/src/main/java/com/hmoa/feature_community/ViewModel/{CommunityPreviewViewModel.kt => CommunityMainViewModel.kt} (86%) delete mode 100644 feature-community/src/main/res/drawable/ic_launcher_background.xml delete mode 100644 feature-community/src/main/res/drawable/ic_launcher_foreground.xml delete mode 100644 feature-community/src/main/res/mipmap-anydpi-v26/ic_launcher.xml delete mode 100644 feature-community/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml delete mode 100644 feature-community/src/main/res/mipmap-hdpi/ic_launcher.webp delete mode 100644 feature-community/src/main/res/mipmap-hdpi/ic_launcher_round.webp delete mode 100644 feature-community/src/main/res/mipmap-mdpi/ic_launcher.webp delete mode 100644 feature-community/src/main/res/mipmap-mdpi/ic_launcher_round.webp delete mode 100644 feature-community/src/main/res/mipmap-xhdpi/ic_launcher.webp delete mode 100644 feature-community/src/main/res/mipmap-xhdpi/ic_launcher_round.webp delete mode 100644 feature-community/src/main/res/mipmap-xxhdpi/ic_launcher.webp delete mode 100644 feature-community/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp delete mode 100644 feature-community/src/main/res/mipmap-xxxhdpi/ic_launcher.webp delete mode 100644 feature-community/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp delete mode 100644 feature-community/src/main/res/values-night/themes.xml delete mode 100644 feature-community/src/main/res/values/colors.xml delete mode 100644 feature-community/src/main/res/values/strings.xml delete mode 100644 feature-community/src/main/res/values/themes.xml delete mode 100644 feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/ExampleInstrumentedTest.kt create mode 100644 feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/HbtiSurveyResultScreenTest.kt create mode 100644 feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/HbtiSurveyScreenTest.kt create mode 100644 feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/NotePickScreenTest.kt create mode 100644 feature-hbti/src/androidTest/java/com/hmoa/feature_hbti/PerfumeRecommendationResultScreenTest.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/paging/ReviewPagingSource.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/AddAddressScreen.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/DeletableTagBadgeScroller.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/EditReviewScreen.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/HbtiSurveyLoadingScreen.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/NotePickResultScreen.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/OrderResultScreen.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/OrderScreen.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/ReviewScreen.kt delete mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/SelectSpiceScreen.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/screen/WriteReviewScreen.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/AddAddressViewModel.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/EditReviewViewModel.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiHomeViewModel.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiProcessViewmodel.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/HbtiSurveyLoadingViewmodel.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/NotePickResultViewModel.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/OrderViewModel.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/ReviewViewModel.kt create mode 100644 feature-hbti/src/main/java/com/hmoa/feature_hbti/viewmodel/WriteReviewViewModel.kt create mode 100644 feature-hbti/src/test/java/com/hmoa/feature_hbti/HbtiSurveyViewModelTest.kt create mode 100644 feature-hbti/src/test/java/com/hmoa/feature_hbti/NoteOrderQuantityPickViewmodelTest.kt create mode 100644 feature-hbti/src/test/java/com/hmoa/feature_hbti/NotePickViewmodelTest.kt create mode 100644 feature-hbti/src/test/java/com/hmoa/feature_hbti/PerfumeRecommendationResultViewmodelTest.kt create mode 100644 feature-hbti/src/test/java/com/hmoa/feature_hbti/PerfumeRecommendationViewmodelTest.kt create mode 100644 feature-hbti/src/test/java/com/hmoa/feature_hbti/TestCoroutineRule.kt delete mode 100644 feature-like/.gitignore delete mode 100644 feature-like/build.gradle.kts delete mode 100644 feature-like/proguard-rules.pro delete mode 100644 feature-like/src/androidTest/java/com/example/feature_like/ExampleInstrumentedTest.kt delete mode 100644 feature-like/src/main/AndroidManifest.xml delete mode 100644 feature-like/src/main/java/com/hmoa/feature_like/Screen/NoSavePerfumeScreen.kt delete mode 100644 feature-like/src/main/java/com/hmoa/feature_like/ViewModel/LikeViewModel.kt delete mode 100644 feature-like/src/main/res/drawable/ic_launcher_background.xml delete mode 100644 feature-like/src/main/res/drawable/ic_launcher_foreground.xml delete mode 100644 feature-like/src/test/java/com/example/feature_like/ExampleUnitTest.kt rename feature-like/src/main/java/com/hmoa/feature_like/Screen/LikeScreen.kt => feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyFavoritePrefumePage.kt (60%) create mode 100644 feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/MyReview.kt delete mode 100644 feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/NoDataPage.kt create mode 100644 feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/OrderRecordPage.kt create mode 100644 feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/RefundPage.kt create mode 100644 feature-userInfo/src/main/java/com/hmoa/feature_userinfo/Screen/RefundRecordPage.kt rename feature-userInfo/src/main/java/com/hmoa/feature_userinfo/{ => paging}/CommentPagingSource.kt (97%) rename feature-userInfo/src/main/java/com/hmoa/feature_userinfo/{ => paging}/CommunityPagingSource.kt (97%) rename feature-userInfo/src/main/java/com/hmoa/feature_userinfo/{ => paging}/FavoriteCommentPagingSource.kt (97%) create mode 100644 feature-userInfo/src/main/java/com/hmoa/feature_userinfo/paging/OrderPagingSource.kt create mode 100644 feature-userInfo/src/main/java/com/hmoa/feature_userinfo/paging/RefundRecordPagingSource.kt create mode 100644 feature-userInfo/src/main/java/com/hmoa/feature_userinfo/paging/ReviewPagingSource.kt create mode 100644 feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyFavoritePerfumeViewModel.kt create mode 100644 feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/MyReviewViewModel.kt create mode 100644 feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/OrderRecordViewModel.kt create mode 100644 feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/RefundRecordViewModel.kt create mode 100644 feature-userInfo/src/main/java/com/hmoa/feature_userinfo/viewModel/RefundViewModel.kt create mode 100644 feature-userInfo/src/test/java/com/hmoa/feature_userinfo/ExampleUnitTest.kt delete mode 100755 load-env-from-json.sh rename reset-local-properties.sh => reset-hmoa-android-secrets.sh (85%) diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index aafb75163..56dafa4a3 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -52,9 +52,5 @@ jobs: - 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..765e11f74 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ local.properties deploymentTargetDropDown.xml /config.json +/.idea/other.xml +/.idea/deploymentTargetSelector.xml \ No newline at end of file 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..4c3ff026b 100644 --- a/.idea/deploymentTargetSelector.xml +++ b/.idea/deploymentTargetSelector.xml @@ -4,10 +4,10 @@