diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml index 9f9d1365..d88922f2 100644 --- a/.idea/deploymentTargetSelector.xml +++ b/.idea/deploymentTargetSelector.xml @@ -4,7 +4,7 @@ - + \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 65724b69..9a57526f 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 = 30 - versionName = "1.1.4" + versionCode = 33 + versionName = "1.2.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" manifestPlaceholders["REDIRECTION_PATH"] = localProperties["REDIRECTION_PATH"] as String diff --git a/core-model/build.gradle.kts b/core-model/build.gradle.kts index d2d13555..8f0bd237 100644 --- a/core-model/build.gradle.kts +++ b/core-model/build.gradle.kts @@ -21,14 +21,11 @@ tasks { dependencies { val kotlinx_version = "1.5.0" - val kotlinx_collections_immutable_version = "0.3.8" - + implementation("io.ktor:ktor-client-serialization:2.3.7") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinx_version") testImplementation("junit:junit:4.13.2") testImplementation("org.junit.jupiter:junit-jupiter-api:5.3.1") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.3.1") implementation(kotlin("stdlib")) - compileOnly("com.github.skydoves:compose-stable-marker:1.0.5") - implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:$kotlinx_collections_immutable_version") } diff --git a/core-model/src/main/java/com/hmoa/core_model/response/HomeMenuDefaultResponseDto.kt b/core-model/src/main/java/com/hmoa/core_model/response/HomeMenuDefaultResponseDto.kt index 04dbf0a4..b47bb275 100644 --- a/core-model/src/main/java/com/hmoa/core_model/response/HomeMenuDefaultResponseDto.kt +++ b/core-model/src/main/java/com/hmoa/core_model/response/HomeMenuDefaultResponseDto.kt @@ -1,12 +1,9 @@ package com.hmoa.core_model.response -import androidx.compose.runtime.Immutable -import kotlinx.collections.immutable.ImmutableList import kotlinx.serialization.Serializable -@Immutable @Serializable data class HomeMenuDefaultResponseDto( - val perfumeList: ImmutableList, + val perfumeList: List, val title: String ) diff --git a/core-model/src/main/java/com/hmoa/core_model/response/HomeMenuPerfumeResponseDto.kt b/core-model/src/main/java/com/hmoa/core_model/response/HomeMenuPerfumeResponseDto.kt index 25c388b2..e3ba5e4e 100644 --- a/core-model/src/main/java/com/hmoa/core_model/response/HomeMenuPerfumeResponseDto.kt +++ b/core-model/src/main/java/com/hmoa/core_model/response/HomeMenuPerfumeResponseDto.kt @@ -1,10 +1,8 @@ package com.hmoa.core_model.response -import androidx.compose.runtime.Immutable import kotlinx.serialization.Serializable @Serializable -@Immutable data class HomeMenuPerfumeResponseDto( val brandName: String, val imgUrl: String, 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 885c5ed5..1fd9eaf8 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-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 5ea6cc0e..43cf5dda 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 @@ -34,7 +34,6 @@ import com.hmoa.core_domain.entity.data.AllPerfumeScreenId import com.hmoa.core_model.response.HomeMenuDefaultResponseDto import com.hmoa.core_model.response.HomeMenuPerfumeResponseDto import com.hmoa.feature_home.viewmodel.HomeViewModel -import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList @Composable @@ -104,7 +103,11 @@ fun TopMenu( ) } FirstMenuView( - (firstMenuWithBannerState as HomeViewModel.BannerWithFirstMenuState.Data).firstMenu!!, + (firstMenuWithBannerState as HomeViewModel.BannerWithFirstMenuState.Data).firstMenu + ?: HomeMenuDefaultResponseDto( + perfumeList = emptyList().toImmutableList(), + title = "" + ), { onPerfumeClick(it) }) } @@ -128,7 +131,7 @@ fun BottomMenu( BottomMenuContent( onPerfumeClick = { onPerfumeClick(it) }, onAllPerfumeClick = { onAllPerfumeClick(it) }, - (bottomMenuState as HomeViewModel.BottomMenuState.Data).bottomMenu!! + (bottomMenuState as HomeViewModel.BottomMenuState.Data).bottomMenu ) HmoaCompanyMetaData() } @@ -289,7 +292,7 @@ private fun mapIndexToAllPerfumeScreenId(index: Int): AllPerfumeScreenId { private fun BottomMenuContent( onPerfumeClick: (perfumeId: Int) -> Unit, onAllPerfumeClick: (screenId: AllPerfumeScreenId) -> Unit, - bottomMenu: ImmutableList, + bottomMenu: List, ) { Column( modifier = Modifier @@ -417,7 +420,7 @@ fun BottomMenuView( ) } LazyRow() { - items(data!!.perfumeList) { + items(data?.perfumeList ?: emptyList()) { Column(modifier = Modifier.clickable { onPerfumeClick(it.perfumeId) }) { PerfumeItemView( it.imgUrl, it.perfumeName, it.brandName, 126, 126, 0.9f, 0.9f, CustomColor.gray1, 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 21e7537d..0b719a1d 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 @@ -59,7 +59,10 @@ class HomeViewModel @Inject constructor( when (it) { is Result.Success -> { _bottomMenuState.value = - BottomMenuState.Data(it.data.data?.toImmutableList()) + BottomMenuState.Data( + it.data.data?.toImmutableList() + ?: emptyList().toImmutableList() + ) } is Result.Error -> { @@ -91,7 +94,7 @@ class HomeViewModel @Inject constructor( data object Loading : BottomMenuState data class Data( //모델 패키지로 분리해서 분해해서 사용하자. 외부 모듈이니까 unstable인 건 어쩔 수 없음 - val bottomMenu: ImmutableList?, + val bottomMenu: ImmutableList, ) : BottomMenuState data object Error : BottomMenuState 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 5a2eadc2..6ebca983 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, diff --git a/feature-perfume/build.gradle.kts b/feature-perfume/build.gradle.kts index c6c00500..3e9a858b 100644 --- a/feature-perfume/build.gradle.kts +++ b/feature-perfume/build.gradle.kts @@ -36,6 +36,18 @@ android { buildFeatures { compose = true } + tasks.withType() { + compilerOptions.freeCompilerArgs.addAll( + "-P", + "plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=${project.buildDir.absolutePath}/compose_metrics", + ) + } + tasks.withType() { + compilerOptions.freeCompilerArgs.addAll( + "-P", + "plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=${project.buildDir.absolutePath}/compose_reports", + ) + } } dependencies { @@ -62,7 +74,6 @@ dependencies { testAnnotationProcessor("com.google.dagger:hilt-compiler:$hilt_version") implementation("androidx.hilt:hilt-navigation-compose:$hilt_nav_compose_version") kapt("androidx.hilt:hilt-compiler:$hilt_viewmodel_version") - implementation("androidx.core:core-ktx:1.9.0") implementation("androidx.appcompat:appcompat:1.6.1") androidTestImplementation("androidx.test.ext:junit:1.1.5") 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 0cdb323f..74a3f2db 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 ) {