From 391f561891689481c4017b4dff81123ac35ba242 Mon Sep 17 00:00:00 2001 From: KwakEuiJin Date: Wed, 20 Dec 2023 22:39:20 +0900 Subject: [PATCH 1/9] [feat/review_apu]: Add Review Api --- .../everymeal_android/di/NetworkModule.kt | 9 +++- .../everymeal_android/di/RepositoryModule.kt | 14 ++++- .../datasource/review/ReviewDataSource.kt | 18 +++++++ .../datasource/review/ReviewDataSourceImpl.kt | 39 ++++++++++++++ .../com/everymeal/data/model/BaseResponse.kt | 6 ++- .../data/model/review/ReviewListResponse.kt | 54 +++++++++++++++++++ .../data/model/review/ReviewRequest.kt | 35 ++++++++++++ .../{ => auth}/DefaultAuthRepository.kt | 2 +- .../review/DefaultReviewRepository.kt | 39 ++++++++++++++ .../data/service/review/ReviewApi.kt | 38 +++++++++++++ .../domain/model/review/ReviewDetail.kt | 18 +++++++ .../domain/model/review/UserReview.kt | 8 +++ .../repository/review/ReviewRepository.kt | 11 ++++ .../usecase/review/PostReviewUseCase.kt | 13 +++++ .../presentation/ui/review/ReviewScreen.kt | 7 +++ .../ui/review/ReviewScreenContract.kt | 8 +++ .../ui/review/ReviewScreenViewModel.kt | 21 +++++++- 17 files changed, 334 insertions(+), 6 deletions(-) create mode 100644 data/src/main/java/com/everymeal/data/datasource/review/ReviewDataSource.kt create mode 100644 data/src/main/java/com/everymeal/data/datasource/review/ReviewDataSourceImpl.kt create mode 100644 data/src/main/java/com/everymeal/data/model/review/ReviewListResponse.kt create mode 100644 data/src/main/java/com/everymeal/data/model/review/ReviewRequest.kt rename data/src/main/java/com/everymeal/data/repository/{ => auth}/DefaultAuthRepository.kt (91%) create mode 100644 data/src/main/java/com/everymeal/data/repository/review/DefaultReviewRepository.kt create mode 100644 data/src/main/java/com/everymeal/data/service/review/ReviewApi.kt create mode 100644 domain/src/main/java/com/everymeal/domain/model/review/ReviewDetail.kt create mode 100644 domain/src/main/java/com/everymeal/domain/model/review/UserReview.kt create mode 100644 domain/src/main/java/com/everymeal/domain/repository/review/ReviewRepository.kt create mode 100644 domain/src/main/java/com/everymeal/domain/usecase/review/PostReviewUseCase.kt diff --git a/app/src/main/java/com/everymeal/everymeal_android/di/NetworkModule.kt b/app/src/main/java/com/everymeal/everymeal_android/di/NetworkModule.kt index efaacb05..597ba53f 100644 --- a/app/src/main/java/com/everymeal/everymeal_android/di/NetworkModule.kt +++ b/app/src/main/java/com/everymeal/everymeal_android/di/NetworkModule.kt @@ -2,6 +2,7 @@ package com.everymeal.everymeal_android.di import com.everymeal.data.service.auth.AuthApi import com.everymeal.data.service.onboarding.OnboardingApi +import com.everymeal.data.service.review.ReviewApi import com.everymeal.everymeal_android.BuildConfig import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory import dagger.Module @@ -53,4 +54,10 @@ object NetworkModule { fun provideAuthApi(retrofit: Retrofit): AuthApi { return retrofit.create(AuthApi::class.java) } -} \ No newline at end of file + + @Provides + @Singleton + fun provideReviewApi(retrofit: Retrofit): ReviewApi { + return retrofit.create(ReviewApi::class.java) + } +} diff --git a/app/src/main/java/com/everymeal/everymeal_android/di/RepositoryModule.kt b/app/src/main/java/com/everymeal/everymeal_android/di/RepositoryModule.kt index 1b437a64..95516313 100644 --- a/app/src/main/java/com/everymeal/everymeal_android/di/RepositoryModule.kt +++ b/app/src/main/java/com/everymeal/everymeal_android/di/RepositoryModule.kt @@ -7,7 +7,7 @@ import com.everymeal.data.datasource.local.LocalDataSourceImpl import com.everymeal.data.datasource.onboarding.OnboardingDataSource import com.everymeal.data.datasource.onboarding.OnboardingDataSourceImpl import com.everymeal.data.repository.local.LocalRepositoryImpl -import com.everymeal.data.repository.DefaultAuthRepository +import com.everymeal.data.repository.auth.DefaultAuthRepository import com.everymeal.data.repository.onboarding.OnboardingRepositoryImpl import com.everymeal.domain.repository.local.LocalRepository import com.everymeal.domain.repository.auth.AuthRepository @@ -57,4 +57,16 @@ abstract class RepositoryModule { abstract fun bindAuthRepository( defaultAuthRepository: DefaultAuthRepository ): AuthRepository + + @Singleton + @Binds + abstract fun bindReviewDataSource( + defaultAuthRepository: DefaultAuthRepository + ): AuthRepository + + @Singleton + @Binds + abstract fun bindReviewRepository( + defaultAuthRepository: DefaultAuthRepository + ): AuthRepository } diff --git a/data/src/main/java/com/everymeal/data/datasource/review/ReviewDataSource.kt b/data/src/main/java/com/everymeal/data/datasource/review/ReviewDataSource.kt new file mode 100644 index 00000000..514a4ea0 --- /dev/null +++ b/data/src/main/java/com/everymeal/data/datasource/review/ReviewDataSource.kt @@ -0,0 +1,18 @@ +package com.everymeal.data.datasource.review + +import com.everymeal.data.model.review.ReviewListResponse +import com.everymeal.data.model.review.ReviewRequest + +interface ReviewDataSource { + suspend fun putReview(reviewIdx: Int, reviewRequest: ReviewRequest): Result + + suspend fun deleteReview(reviewIdx: Int): Result + suspend fun getReviewList( + cursorIdx: Int, + mealIdx: Int, + pageSize: Int + ): Result + + suspend fun postReview(reviewRequest: ReviewRequest): Result + +} diff --git a/data/src/main/java/com/everymeal/data/datasource/review/ReviewDataSourceImpl.kt b/data/src/main/java/com/everymeal/data/datasource/review/ReviewDataSourceImpl.kt new file mode 100644 index 00000000..47aea492 --- /dev/null +++ b/data/src/main/java/com/everymeal/data/datasource/review/ReviewDataSourceImpl.kt @@ -0,0 +1,39 @@ +package com.everymeal.data.datasource.review + +import com.everymeal.data.model.review.ReviewListResponse +import com.everymeal.data.model.review.ReviewRequest +import com.everymeal.data.model.unwrapRunCatching +import com.everymeal.data.service.review.ReviewApi +import javax.inject.Inject + +class ReviewDataSourceImpl @Inject constructor( + private val reviewApi: ReviewApi +) : ReviewDataSource { + override suspend fun putReview( + reviewIdx: Int, + reviewRequest: ReviewRequest + ): Result = unwrapRunCatching { reviewApi.putReview(reviewIdx, reviewRequest) } + + + override suspend fun deleteReview(reviewIdx: Int): Result = unwrapRunCatching { + reviewApi.deleteReview(reviewIdx) + } + + override suspend fun getReviewList( + cursorIdx: Int, + mealIdx: Int, + pageSize: Int + ): Result = + unwrapRunCatching { + reviewApi.getReviewList( + cursorIdx, + mealIdx, + pageSize + ) + } + + + override suspend fun postReview( + reviewRequest: ReviewRequest + ): Result = unwrapRunCatching { reviewApi.postReview(reviewRequest) } +} diff --git a/data/src/main/java/com/everymeal/data/model/BaseResponse.kt b/data/src/main/java/com/everymeal/data/model/BaseResponse.kt index ba187ad5..41366b92 100644 --- a/data/src/main/java/com/everymeal/data/model/BaseResponse.kt +++ b/data/src/main/java/com/everymeal/data/model/BaseResponse.kt @@ -11,4 +11,8 @@ data class BaseResponse( fun Result>.unwrapData(): Result { return this.map { it.data } -} \ No newline at end of file +} + +suspend fun unwrapRunCatching(block: suspend () -> BaseResponse): Result { + return runCatching { block() }.unwrapData() +} diff --git a/data/src/main/java/com/everymeal/data/model/review/ReviewListResponse.kt b/data/src/main/java/com/everymeal/data/model/review/ReviewListResponse.kt new file mode 100644 index 00000000..e4861abe --- /dev/null +++ b/data/src/main/java/com/everymeal/data/model/review/ReviewListResponse.kt @@ -0,0 +1,54 @@ +package com.everymeal.data.model.review + + +import com.everymeal.domain.model.review.Review +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ReviewListResponse( + @SerialName("reviewPagingList") + val reviewPagingList: List? = null, + @SerialName("reviewTotalCnt") + val reviewTotalCnt: Int? = null +) { + @Serializable + data class ReviewPaging( + @SerialName("content") + val content: String? = null, + @SerialName("grade") + val grade: Int? = null, + @SerialName("imageList") + val imageList: List? = null, + @SerialName("mealCategory") + val mealCategory: String? = null, + @SerialName("mealType") + val mealType: String? = null, + @SerialName("restaurantName") + val restaurantName: String? = null, + @SerialName("reviewIdx") + val reviewIdx: Int? = null, + @SerialName("reviewMarksCnt") + val reviewMarksCnt: Int? = null + ) { + fun toReviewDetail(): Review.ReviewDetail { + return Review.ReviewDetail( + content = content ?: "", + grade = grade ?: 0, + imageList = imageList ?: listOf(), + mealCategory = mealCategory ?: "", + mealType = mealType ?: "", + restaurantName = restaurantName ?: "", + reviewIdx = reviewIdx ?: 0, + reviewMarksCnt = reviewMarksCnt ?: 0 + ) + } + } + + fun toReview(): Review { + return Review( + reviewPagingList = reviewPagingList?.map { it.toReviewDetail() } ?: listOf(), + reviewTotalCnt = reviewTotalCnt ?: 0 + ) + } +} diff --git a/data/src/main/java/com/everymeal/data/model/review/ReviewRequest.kt b/data/src/main/java/com/everymeal/data/model/review/ReviewRequest.kt new file mode 100644 index 00000000..c77b1750 --- /dev/null +++ b/data/src/main/java/com/everymeal/data/model/review/ReviewRequest.kt @@ -0,0 +1,35 @@ +package com.everymeal.data.model.review + +import com.everymeal.domain.model.review.UserReview +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ReviewRequest( + @SerialName("mealIdx") + val mealIdx: Int, + @SerialName("grade") + val grade: Int, + @SerialName("content") + val content: String, + @SerialName("imageList") + val imageList: List +) { + fun toUserReview(): UserReview { + return UserReview( + mealIdx = mealIdx, + grade = grade, + content = content, + imageList = imageList + ) + } +} + +fun UserReview.toReviewRequest(): ReviewRequest { + return ReviewRequest( + mealIdx = mealIdx, + grade = grade, + content = content, + imageList = imageList + ) +} diff --git a/data/src/main/java/com/everymeal/data/repository/DefaultAuthRepository.kt b/data/src/main/java/com/everymeal/data/repository/auth/DefaultAuthRepository.kt similarity index 91% rename from data/src/main/java/com/everymeal/data/repository/DefaultAuthRepository.kt rename to data/src/main/java/com/everymeal/data/repository/auth/DefaultAuthRepository.kt index 5fdbf858..13b23e9a 100644 --- a/data/src/main/java/com/everymeal/data/repository/DefaultAuthRepository.kt +++ b/data/src/main/java/com/everymeal/data/repository/auth/DefaultAuthRepository.kt @@ -1,4 +1,4 @@ -package com.everymeal.data.repository +package com.everymeal.data.repository.auth import com.everymeal.data.datasource.auth.AuthRemoteDataSource import com.everymeal.domain.model.auth.Email diff --git a/data/src/main/java/com/everymeal/data/repository/review/DefaultReviewRepository.kt b/data/src/main/java/com/everymeal/data/repository/review/DefaultReviewRepository.kt new file mode 100644 index 00000000..7b1ab183 --- /dev/null +++ b/data/src/main/java/com/everymeal/data/repository/review/DefaultReviewRepository.kt @@ -0,0 +1,39 @@ +package com.everymeal.data.repository.review + +import com.everymeal.data.datasource.review.ReviewDataSource +import com.everymeal.data.model.review.toReviewRequest +import com.everymeal.domain.model.review.Review +import com.everymeal.domain.model.review.UserReview +import com.everymeal.domain.repository.review.ReviewRepository +import javax.inject.Inject + +class DefaultReviewRepository @Inject constructor( + private val reviewDataSource: ReviewDataSource +) : ReviewRepository { + override suspend fun putReview( + reviewIdx: Int, + userReview: UserReview, + ): Result = reviewDataSource.putReview(reviewIdx, userReview.toReviewRequest()) + + + override suspend fun deleteReview(reviewIdx: Int): Result = + reviewDataSource.deleteReview(reviewIdx) + + override suspend fun getReviewList( + cursorIdx: Int, + mealIdx: Int, + pageSize: Int + ): Result = + reviewDataSource.getReviewList(cursorIdx, mealIdx, pageSize).map { + it.toReview() + } + + + override suspend fun postReview( + userReview: UserReview + ): Result { + return reviewDataSource.postReview( + userReview.toReviewRequest() + ) + } +} diff --git a/data/src/main/java/com/everymeal/data/service/review/ReviewApi.kt b/data/src/main/java/com/everymeal/data/service/review/ReviewApi.kt new file mode 100644 index 00000000..25be0111 --- /dev/null +++ b/data/src/main/java/com/everymeal/data/service/review/ReviewApi.kt @@ -0,0 +1,38 @@ +package com.everymeal.data.service.review + +import com.everymeal.data.model.BaseResponse +import com.everymeal.data.model.review.ReviewListResponse +import com.everymeal.data.model.review.ReviewRequest +import retrofit2.http.Body +import retrofit2.http.DELETE +import retrofit2.http.GET +import retrofit2.http.POST +import retrofit2.http.PUT +import retrofit2.http.Path +import retrofit2.http.Query + +interface ReviewApi { + @PUT("/api/v1/reviews/{reviewIdx}") + suspend fun putReview( + @Path("reviewIdx") reviewIdx: Int, + @Body reviewRequest: ReviewRequest + ): BaseResponse + + @DELETE("/api/v1/reviews/{reviewIdx}") + suspend fun deleteReview( + @Path("reviewIdx") reviewIdx: Int + ): BaseResponse + + @GET("/api/v1/reviews") + suspend fun getReviewList( + @Query("cursorIdx") cursorIdx: Int, + @Query("mealIdx") mealIdx: Int, + @Query("pageSize") pageSize: Int, + ): BaseResponse + + @POST("/api/v1/reviews") + suspend fun postReview( + @Body reviewRequest: ReviewRequest + ): BaseResponse + +} diff --git a/domain/src/main/java/com/everymeal/domain/model/review/ReviewDetail.kt b/domain/src/main/java/com/everymeal/domain/model/review/ReviewDetail.kt new file mode 100644 index 00000000..86483247 --- /dev/null +++ b/domain/src/main/java/com/everymeal/domain/model/review/ReviewDetail.kt @@ -0,0 +1,18 @@ +package com.everymeal.domain.model.review + +data class Review( + val reviewPagingList: List, + val reviewTotalCnt: Int +) { + data class ReviewDetail( + val content: String, + val grade: Int, + val imageList: List, + val mealCategory: String, + val mealType: String, + val restaurantName: String, + val reviewIdx: Int, + val reviewMarksCnt: Int + ) +} + diff --git a/domain/src/main/java/com/everymeal/domain/model/review/UserReview.kt b/domain/src/main/java/com/everymeal/domain/model/review/UserReview.kt new file mode 100644 index 00000000..c56f60cc --- /dev/null +++ b/domain/src/main/java/com/everymeal/domain/model/review/UserReview.kt @@ -0,0 +1,8 @@ +package com.everymeal.domain.model.review + +data class UserReview( + val mealIdx: Int, + val grade: Int, + val content: String, + val imageList: List +) diff --git a/domain/src/main/java/com/everymeal/domain/repository/review/ReviewRepository.kt b/domain/src/main/java/com/everymeal/domain/repository/review/ReviewRepository.kt new file mode 100644 index 00000000..03f8ad4b --- /dev/null +++ b/domain/src/main/java/com/everymeal/domain/repository/review/ReviewRepository.kt @@ -0,0 +1,11 @@ +package com.everymeal.domain.repository.review + +import com.everymeal.domain.model.review.Review +import com.everymeal.domain.model.review.UserReview + +interface ReviewRepository { + suspend fun putReview(reviewIdx: Int, userReview: UserReview): Result + suspend fun deleteReview(reviewIdx: Int): Result + suspend fun getReviewList(cursorIdx: Int, mealIdx: Int, pageSize: Int): Result + suspend fun postReview(userReview: UserReview): Result +} diff --git a/domain/src/main/java/com/everymeal/domain/usecase/review/PostReviewUseCase.kt b/domain/src/main/java/com/everymeal/domain/usecase/review/PostReviewUseCase.kt new file mode 100644 index 00000000..4584e5a5 --- /dev/null +++ b/domain/src/main/java/com/everymeal/domain/usecase/review/PostReviewUseCase.kt @@ -0,0 +1,13 @@ +package com.everymeal.domain.usecase.review + +import com.everymeal.domain.model.review.UserReview +import com.everymeal.domain.repository.review.ReviewRepository +import javax.inject.Inject + +class PostReviewUseCase @Inject constructor( + private val reviewRepository: ReviewRepository +) { + suspend operator fun invoke(userReview: UserReview) { + reviewRepository.postReview(userReview) + } +} diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreen.kt index 374c66b1..3b13f0ef 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreen.kt @@ -99,6 +99,13 @@ fun ReviewScreen( viewModel.setEvent(ReviewEvent.OnReviewTextChanged(it)) }, onReviewRegisterClicked = { + viewModel.setEvent(ReviewEvent.PostReview( + reviewValue = viewState.reviewValue, + imageUri = viewState.imageUri, + restaurantType = viewState.restaurantType, + restaurantName = viewState.restaurantName, + starRatingCount = viewState.starRatingStateList.count { it.value } + )) Toast.makeText( context, context.getString(R.string.register_review), diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreenContract.kt b/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreenContract.kt index 36974eee..d353f44f 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreenContract.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreenContract.kt @@ -33,6 +33,14 @@ sealed class ReviewEvent : ViewEvent { data class OnImageSelected( val imageUri: List ) : ReviewEvent() + + data class PostReview( + val reviewValue: String, + val imageUri: List, + val restaurantType: String, + val restaurantName: String, + val starRatingCount: Int, + ) : ReviewEvent() } sealed class ReviewEffect : ViewSideEffect { diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreenViewModel.kt b/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreenViewModel.kt index bd837bc1..2dea2b25 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreenViewModel.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreenViewModel.kt @@ -1,16 +1,20 @@ package com.everymeal.presentation.ui.review import androidx.compose.runtime.mutableStateOf +import androidx.lifecycle.viewModelScope +import com.everymeal.domain.model.review.UserReview +import com.everymeal.domain.usecase.review.PostReviewUseCase import com.everymeal.presentation.base.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class ReviewScreenViewModel @Inject constructor( - + private val postReviewUseCase: PostReviewUseCase ) : BaseViewModel(ReviewState()) { override fun handleEvents(event: ReviewEvent) { - when(event) { + when (event) { is ReviewEvent.OnStarClicked -> { updateState { val newStarRatingStateList = List(starRatingStateList.size) { index -> @@ -37,6 +41,19 @@ class ReviewScreenViewModel @Inject constructor( ) } } + + is ReviewEvent.PostReview -> { + viewModelScope.launch { + val userReview = UserReview( + mealIdx = event.mealIdx, + grade = event.starRatingCount, + content = event.reviewValue, + imageList = event.imageUri.map { it.toString() } + ) + postReviewUseCase(userReview) + } + + } } } } From 77f841ce6ce497a9d2355a86ea6f2b2daf104b85 Mon Sep 17 00:00:00 2001 From: KwakEuiJin Date: Fri, 2 Feb 2024 15:00:07 +0900 Subject: [PATCH 2/9] =?UTF-8?q?[feat/review=5Fapi]:=20Review=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EC=9E=AC=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../everymeal_android/di/NetworkModule.kt | 6 +- .../everymeal_android/di/RepositoryModule.kt | 43 ++--- .../auth/AuthRemoteRemoteDataSourceImpl.kt | 5 +- .../datasource/review/ReviewDataSource.kt | 10 +- .../datasource/review/ReviewDataSourceImpl.kt | 26 +-- ...ReviewRequest.kt => StoreReviewRequest.kt} | 20 +-- .../repository/auth/DefaultAuthRepository.kt | 4 +- .../review/DefaultReviewRepository.kt | 18 +-- .../data/service/review/ReviewApi.kt | 38 ----- .../data/service/review/StoreReviewApi.kt | 32 ++++ domain/build.gradle.kts | 3 +- ...urantEntity.kt => RestaurantDataEntity.kt} | 4 - .../domain/model/review/UserReview.kt | 2 +- .../restaurant/RestaurantRepository.kt | 4 +- .../repository/review/ReviewRepository.kt | 2 - .../com/everymeal/domain/ExampleUnitTest.kt | 5 +- gradle/libs.versions.toml | 4 + .../components/EveryMealRestaurantItem.kt | 46 +++--- .../ui/bottom/BottomNavigation.kt | 2 + .../ui/detail/DetailListScreen.kt | 150 ++++++++++++------ .../presentation/ui/home/HomeContract.kt | 9 +- .../presentation/ui/home/HomeScreen.kt | 49 +++--- .../presentation/ui/home/HomeViewModel.kt | 15 +- .../presentation/ui/main/MainScreen.kt | 21 ++- .../presentation/ui/review/ReviewScreen.kt | 91 ++++------- .../ui/review/ReviewScreenContract.kt | 23 ++- .../ui/review/ReviewScreenViewModel.kt | 13 +- .../ui/review/detail/ReviewDetailScreen.kt | 60 ++++--- .../ui/review/search/ReviewSearchScreen.kt | 76 +++++++++ .../ui/review/write/ReviewWriteScreen.kt | 32 ++-- .../presentation/ui/search/SearchContract.kt | 19 +-- .../presentation/ui/search/SearchScreen.kt | 58 ++++--- .../presentation/ui/search/SearchViewModel.kt | 27 +++- .../ui/search/history/SearchHistoryList.kt | 14 +- .../ui/search/topbar/SearchTopBar.kt | 12 +- 35 files changed, 518 insertions(+), 425 deletions(-) rename data/src/main/java/com/everymeal/data/model/review/{ReviewRequest.kt => StoreReviewRequest.kt} (62%) delete mode 100644 data/src/main/java/com/everymeal/data/service/review/ReviewApi.kt create mode 100644 data/src/main/java/com/everymeal/data/service/review/StoreReviewApi.kt rename domain/src/main/java/com/everymeal/domain/model/restaurant/{GetUnivRestaurantEntity.kt => RestaurantDataEntity.kt} (82%) create mode 100644 presentation/src/main/java/com/everymeal/presentation/ui/review/search/ReviewSearchScreen.kt diff --git a/app/src/main/java/com/everymeal/everymeal_android/di/NetworkModule.kt b/app/src/main/java/com/everymeal/everymeal_android/di/NetworkModule.kt index ef263ed4..70c16498 100644 --- a/app/src/main/java/com/everymeal/everymeal_android/di/NetworkModule.kt +++ b/app/src/main/java/com/everymeal/everymeal_android/di/NetworkModule.kt @@ -3,7 +3,7 @@ package com.everymeal.everymeal_android.di import com.everymeal.data.service.auth.AuthApi import com.everymeal.data.service.onboarding.OnboardingApi import com.everymeal.data.service.restaurant.RestaurantApi -import com.everymeal.data.service.review.ReviewApi +import com.everymeal.data.service.review.StoreReviewApi import com.everymeal.everymeal_android.BuildConfig import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory import dagger.Module @@ -67,7 +67,7 @@ object NetworkModule { @Provides @Singleton - fun provideReviewApi(retrofit: Retrofit): ReviewApi { - return retrofit.create(ReviewApi::class.java) + fun provideReviewApi(retrofit: Retrofit): StoreReviewApi { + return retrofit.create(StoreReviewApi::class.java) } } diff --git a/app/src/main/java/com/everymeal/everymeal_android/di/RepositoryModule.kt b/app/src/main/java/com/everymeal/everymeal_android/di/RepositoryModule.kt index 1fa8cdcd..d557bf53 100644 --- a/app/src/main/java/com/everymeal/everymeal_android/di/RepositoryModule.kt +++ b/app/src/main/java/com/everymeal/everymeal_android/di/RepositoryModule.kt @@ -8,15 +8,18 @@ import com.everymeal.data.datasource.onboarding.OnboardingDataSource import com.everymeal.data.datasource.onboarding.OnboardingDataSourceImpl import com.everymeal.data.datasource.restaurant.RestaurantDataSource import com.everymeal.data.datasource.restaurant.RestaurantDataSourceImpl -import com.everymeal.data.repository.local.LocalRepositoryImpl +import com.everymeal.data.datasource.review.ReviewDataSource +import com.everymeal.data.datasource.review.ReviewDataSourceImpl import com.everymeal.data.repository.auth.DefaultAuthRepository +import com.everymeal.data.repository.local.LocalRepositoryImpl import com.everymeal.data.repository.onboarding.OnboardingRepositoryImpl import com.everymeal.data.repository.restaurant.RestaurantRepositoryImpl -import com.everymeal.domain.repository.local.LocalRepository +import com.everymeal.data.repository.review.DefaultReviewRepository import com.everymeal.domain.repository.auth.AuthRepository +import com.everymeal.domain.repository.local.LocalRepository import com.everymeal.domain.repository.onboarding.OnboardingRepository import com.everymeal.domain.repository.restaurant.RestaurantRepository -import com.everymeal.presentation.ui.home.Restaurant +import com.everymeal.domain.repository.review.ReviewRepository import dagger.Binds import dagger.Module import dagger.hilt.InstallIn @@ -30,60 +33,60 @@ abstract class RepositoryModule { @Singleton @Binds abstract fun bindOnboardingRepository( - onboardingRepositoryImpl: OnboardingRepositoryImpl + onboardingRepositoryImpl: OnboardingRepositoryImpl, ): OnboardingRepository @Singleton @Binds abstract fun bindOnboardingDataSource( - onboardingDataSourceImpl: OnboardingDataSourceImpl + onboardingDataSourceImpl: OnboardingDataSourceImpl, ): OnboardingDataSource @Singleton @Binds abstract fun bindLocalRepository( - localRepositoryImpl: LocalRepositoryImpl + localRepositoryImpl: LocalRepositoryImpl, ): LocalRepository @Singleton @Binds abstract fun bindLocalDataSource( - localDataSourceImpl: LocalDataSourceImpl + localDataSourceImpl: LocalDataSourceImpl, ): LocalDataSource @Singleton @Binds abstract fun bindAuthRemoteDataSource( - authRemoteDataSourceImpl: AuthRemoteRemoteDataSourceImpl + authRemoteDataSourceImpl: AuthRemoteRemoteDataSourceImpl, ): AuthRemoteDataSource - @Singleton - @Binds - abstract fun bindAuthRepository( - defaultAuthRepository: DefaultAuthRepository - ): AuthRepository - @Singleton @Binds abstract fun bindRestaurantDataSource( - restaurantDataSourceImpl: RestaurantDataSourceImpl + restaurantDataSourceImpl: RestaurantDataSourceImpl, ): RestaurantDataSource @Singleton @Binds abstract fun bindRestaurantRepository( - restaurantRepositoryImpl: RestaurantRepositoryImpl + restaurantRepositoryImpl: RestaurantRepositoryImpl, ): RestaurantRepository @Singleton @Binds - abstract fun bindReviewDataSource( - defaultAuthRepository: DefaultAuthRepository + abstract fun bindAuthRepository( + defaultAuthRepository: DefaultAuthRepository, ): AuthRepository + @Singleton + @Binds + abstract fun bindReviewDataSource( + reviewDataSourceImpl: ReviewDataSourceImpl, + ): ReviewDataSource + @Singleton @Binds abstract fun bindReviewRepository( - defaultAuthRepository: DefaultAuthRepository - ): AuthRepository + defaultReviewRepository: DefaultReviewRepository, + ): ReviewRepository } diff --git a/data/src/main/java/com/everymeal/data/datasource/auth/AuthRemoteRemoteDataSourceImpl.kt b/data/src/main/java/com/everymeal/data/datasource/auth/AuthRemoteRemoteDataSourceImpl.kt index 3be62dab..e0e5ea24 100644 --- a/data/src/main/java/com/everymeal/data/datasource/auth/AuthRemoteRemoteDataSourceImpl.kt +++ b/data/src/main/java/com/everymeal/data/datasource/auth/AuthRemoteRemoteDataSourceImpl.kt @@ -1,17 +1,14 @@ package com.everymeal.data.datasource.auth -import com.everymeal.data.model.auth.EmailResponse -import com.everymeal.data.model.auth.toEmail import com.everymeal.data.model.auth.toEmailAuthToken import com.everymeal.data.model.auth.toEmailRequest -import com.everymeal.data.model.unwrapData import com.everymeal.data.service.auth.AuthApi import com.everymeal.domain.model.auth.Email import com.everymeal.domain.model.auth.EmailAuthToken import javax.inject.Inject class AuthRemoteRemoteDataSourceImpl @Inject constructor( - private val authApi: AuthApi + private val authApi: AuthApi, ) : AuthRemoteDataSource { override suspend fun postEmail(email: Email): Result = runCatching { diff --git a/data/src/main/java/com/everymeal/data/datasource/review/ReviewDataSource.kt b/data/src/main/java/com/everymeal/data/datasource/review/ReviewDataSource.kt index 514a4ea0..327428b2 100644 --- a/data/src/main/java/com/everymeal/data/datasource/review/ReviewDataSource.kt +++ b/data/src/main/java/com/everymeal/data/datasource/review/ReviewDataSource.kt @@ -1,18 +1,14 @@ package com.everymeal.data.datasource.review import com.everymeal.data.model.review.ReviewListResponse -import com.everymeal.data.model.review.ReviewRequest +import com.everymeal.data.model.review.StoreReviewRequest interface ReviewDataSource { - suspend fun putReview(reviewIdx: Int, reviewRequest: ReviewRequest): Result - - suspend fun deleteReview(reviewIdx: Int): Result suspend fun getReviewList( cursorIdx: Int, mealIdx: Int, - pageSize: Int + pageSize: Int, ): Result - suspend fun postReview(reviewRequest: ReviewRequest): Result - + suspend fun postReview(storeReviewRequest: StoreReviewRequest): Result } diff --git a/data/src/main/java/com/everymeal/data/datasource/review/ReviewDataSourceImpl.kt b/data/src/main/java/com/everymeal/data/datasource/review/ReviewDataSourceImpl.kt index 47aea492..3aca7eb3 100644 --- a/data/src/main/java/com/everymeal/data/datasource/review/ReviewDataSourceImpl.kt +++ b/data/src/main/java/com/everymeal/data/datasource/review/ReviewDataSourceImpl.kt @@ -1,39 +1,29 @@ package com.everymeal.data.datasource.review import com.everymeal.data.model.review.ReviewListResponse -import com.everymeal.data.model.review.ReviewRequest +import com.everymeal.data.model.review.StoreReviewRequest import com.everymeal.data.model.unwrapRunCatching -import com.everymeal.data.service.review.ReviewApi +import com.everymeal.data.service.review.StoreReviewApi import javax.inject.Inject class ReviewDataSourceImpl @Inject constructor( - private val reviewApi: ReviewApi + private val storeReviewApi: StoreReviewApi, ) : ReviewDataSource { - override suspend fun putReview( - reviewIdx: Int, - reviewRequest: ReviewRequest - ): Result = unwrapRunCatching { reviewApi.putReview(reviewIdx, reviewRequest) } - - - override suspend fun deleteReview(reviewIdx: Int): Result = unwrapRunCatching { - reviewApi.deleteReview(reviewIdx) - } override suspend fun getReviewList( cursorIdx: Int, mealIdx: Int, - pageSize: Int + pageSize: Int, ): Result = unwrapRunCatching { - reviewApi.getReviewList( + storeReviewApi.getStoreReviewsWithId( cursorIdx, mealIdx, - pageSize + pageSize, ) } - override suspend fun postReview( - reviewRequest: ReviewRequest - ): Result = unwrapRunCatching { reviewApi.postReview(reviewRequest) } + storeReviewRequest: StoreReviewRequest, + ): Result = unwrapRunCatching { storeReviewApi.postStoreReview(storeReviewRequest) } } diff --git a/data/src/main/java/com/everymeal/data/model/review/ReviewRequest.kt b/data/src/main/java/com/everymeal/data/model/review/StoreReviewRequest.kt similarity index 62% rename from data/src/main/java/com/everymeal/data/model/review/ReviewRequest.kt rename to data/src/main/java/com/everymeal/data/model/review/StoreReviewRequest.kt index c77b1750..4e015381 100644 --- a/data/src/main/java/com/everymeal/data/model/review/ReviewRequest.kt +++ b/data/src/main/java/com/everymeal/data/model/review/StoreReviewRequest.kt @@ -5,31 +5,31 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable -data class ReviewRequest( - @SerialName("mealIdx") - val mealIdx: Int, +data class StoreReviewRequest( + @SerialName("idx") + val idx: Int, @SerialName("grade") val grade: Int, @SerialName("content") val content: String, @SerialName("imageList") - val imageList: List + val imageList: List, ) { fun toUserReview(): UserReview { return UserReview( - mealIdx = mealIdx, + idx = idx, grade = grade, content = content, - imageList = imageList + imageList = imageList, ) } } -fun UserReview.toReviewRequest(): ReviewRequest { - return ReviewRequest( - mealIdx = mealIdx, +fun UserReview.toReviewRequest(): StoreReviewRequest { + return StoreReviewRequest( + idx = idx, grade = grade, content = content, - imageList = imageList + imageList = imageList, ) } diff --git a/data/src/main/java/com/everymeal/data/repository/auth/DefaultAuthRepository.kt b/data/src/main/java/com/everymeal/data/repository/auth/DefaultAuthRepository.kt index bb46dee1..43c8c9eb 100644 --- a/data/src/main/java/com/everymeal/data/repository/auth/DefaultAuthRepository.kt +++ b/data/src/main/java/com/everymeal/data/repository/auth/DefaultAuthRepository.kt @@ -7,7 +7,7 @@ import com.everymeal.domain.repository.auth.AuthRepository import javax.inject.Inject class DefaultAuthRepository @Inject constructor( - private val authRemoteDataSource: AuthRemoteDataSource + private val authRemoteDataSource: AuthRemoteDataSource, ) : AuthRepository { override suspend fun postEmail(email: Email): Result { return authRemoteDataSource.postEmail(email) @@ -15,7 +15,7 @@ class DefaultAuthRepository @Inject constructor( override suspend fun verifyToken( emailAuthToken: String, - emailAuthValue: String + emailAuthValue: String, ): Result { return authRemoteDataSource.verifyToken(emailAuthToken, emailAuthValue) } diff --git a/data/src/main/java/com/everymeal/data/repository/review/DefaultReviewRepository.kt b/data/src/main/java/com/everymeal/data/repository/review/DefaultReviewRepository.kt index 7b1ab183..6abb844c 100644 --- a/data/src/main/java/com/everymeal/data/repository/review/DefaultReviewRepository.kt +++ b/data/src/main/java/com/everymeal/data/repository/review/DefaultReviewRepository.kt @@ -8,32 +8,22 @@ import com.everymeal.domain.repository.review.ReviewRepository import javax.inject.Inject class DefaultReviewRepository @Inject constructor( - private val reviewDataSource: ReviewDataSource + private val reviewDataSource: ReviewDataSource, ) : ReviewRepository { - override suspend fun putReview( - reviewIdx: Int, - userReview: UserReview, - ): Result = reviewDataSource.putReview(reviewIdx, userReview.toReviewRequest()) - - - override suspend fun deleteReview(reviewIdx: Int): Result = - reviewDataSource.deleteReview(reviewIdx) - override suspend fun getReviewList( cursorIdx: Int, mealIdx: Int, - pageSize: Int + pageSize: Int, ): Result = reviewDataSource.getReviewList(cursorIdx, mealIdx, pageSize).map { it.toReview() } - override suspend fun postReview( - userReview: UserReview + userReview: UserReview, ): Result { return reviewDataSource.postReview( - userReview.toReviewRequest() + userReview.toReviewRequest(), ) } } diff --git a/data/src/main/java/com/everymeal/data/service/review/ReviewApi.kt b/data/src/main/java/com/everymeal/data/service/review/ReviewApi.kt deleted file mode 100644 index 25be0111..00000000 --- a/data/src/main/java/com/everymeal/data/service/review/ReviewApi.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.everymeal.data.service.review - -import com.everymeal.data.model.BaseResponse -import com.everymeal.data.model.review.ReviewListResponse -import com.everymeal.data.model.review.ReviewRequest -import retrofit2.http.Body -import retrofit2.http.DELETE -import retrofit2.http.GET -import retrofit2.http.POST -import retrofit2.http.PUT -import retrofit2.http.Path -import retrofit2.http.Query - -interface ReviewApi { - @PUT("/api/v1/reviews/{reviewIdx}") - suspend fun putReview( - @Path("reviewIdx") reviewIdx: Int, - @Body reviewRequest: ReviewRequest - ): BaseResponse - - @DELETE("/api/v1/reviews/{reviewIdx}") - suspend fun deleteReview( - @Path("reviewIdx") reviewIdx: Int - ): BaseResponse - - @GET("/api/v1/reviews") - suspend fun getReviewList( - @Query("cursorIdx") cursorIdx: Int, - @Query("mealIdx") mealIdx: Int, - @Query("pageSize") pageSize: Int, - ): BaseResponse - - @POST("/api/v1/reviews") - suspend fun postReview( - @Body reviewRequest: ReviewRequest - ): BaseResponse - -} diff --git a/data/src/main/java/com/everymeal/data/service/review/StoreReviewApi.kt b/data/src/main/java/com/everymeal/data/service/review/StoreReviewApi.kt new file mode 100644 index 00000000..06100a94 --- /dev/null +++ b/data/src/main/java/com/everymeal/data/service/review/StoreReviewApi.kt @@ -0,0 +1,32 @@ +package com.everymeal.data.service.review + +import com.everymeal.data.model.BaseResponse +import com.everymeal.data.model.review.ReviewListResponse +import com.everymeal.data.model.review.StoreReviewRequest +import retrofit2.http.Body +import retrofit2.http.GET +import retrofit2.http.POST +import retrofit2.http.Query + +interface StoreReviewApi { + @GET("/api/v1/stores/{index}/reviews") + suspend fun getStoreReviewsWithId( + @Query("index") index: Int, + @Query("offset") offset: Int, + @Query("limit") limit: Int, + ): BaseResponse + + @GET("/api/v1/stores/reviews") + suspend fun getStoresReviews( + @Query("offset") offset: Int, + @Query("limit") limit: Int, + @Query("order") order: String, + @Query("group") group: String, + @Query("grade") grade: Int, + ): BaseResponse + + @POST("/api/v1/reviews/store") + suspend fun postStoreReview( + @Body storeReviewRequest: StoreReviewRequest, + ): BaseResponse +} diff --git a/domain/build.gradle.kts b/domain/build.gradle.kts index e3f42c70..e8a5b540 100644 --- a/domain/build.gradle.kts +++ b/domain/build.gradle.kts @@ -15,5 +15,6 @@ dependencies { // Coroutines implementation(libs.kotlin.coroutines) - implementation("androidx.paging:paging-common:3.2.0-rc01") + implementation(libs.androidx.paging.common.v320rc01) + testImplementation(libs.junit.jupiter) } diff --git a/domain/src/main/java/com/everymeal/domain/model/restaurant/GetUnivRestaurantEntity.kt b/domain/src/main/java/com/everymeal/domain/model/restaurant/RestaurantDataEntity.kt similarity index 82% rename from domain/src/main/java/com/everymeal/domain/model/restaurant/GetUnivRestaurantEntity.kt rename to domain/src/main/java/com/everymeal/domain/model/restaurant/RestaurantDataEntity.kt index 0ef6ab29..00353e5c 100644 --- a/domain/src/main/java/com/everymeal/domain/model/restaurant/GetUnivRestaurantEntity.kt +++ b/domain/src/main/java/com/everymeal/domain/model/restaurant/RestaurantDataEntity.kt @@ -1,9 +1,5 @@ package com.everymeal.domain.model.restaurant -data class GetUnivRestaurantEntity( - val data: List -) - data class RestaurantDataEntity( val idx: Int, val name: String, diff --git a/domain/src/main/java/com/everymeal/domain/model/review/UserReview.kt b/domain/src/main/java/com/everymeal/domain/model/review/UserReview.kt index c56f60cc..994e2733 100644 --- a/domain/src/main/java/com/everymeal/domain/model/review/UserReview.kt +++ b/domain/src/main/java/com/everymeal/domain/model/review/UserReview.kt @@ -1,7 +1,7 @@ package com.everymeal.domain.model.review data class UserReview( - val mealIdx: Int, + val idx: Int, val grade: Int, val content: String, val imageList: List diff --git a/domain/src/main/java/com/everymeal/domain/repository/restaurant/RestaurantRepository.kt b/domain/src/main/java/com/everymeal/domain/repository/restaurant/RestaurantRepository.kt index 9038d73e..49b359b2 100644 --- a/domain/src/main/java/com/everymeal/domain/repository/restaurant/RestaurantRepository.kt +++ b/domain/src/main/java/com/everymeal/domain/repository/restaurant/RestaurantRepository.kt @@ -11,5 +11,5 @@ interface RestaurantRepository { order: String, group: String? = null, grade: String? = null, - ) : Flow> -} \ No newline at end of file + ): Flow> +} diff --git a/domain/src/main/java/com/everymeal/domain/repository/review/ReviewRepository.kt b/domain/src/main/java/com/everymeal/domain/repository/review/ReviewRepository.kt index 03f8ad4b..d999da28 100644 --- a/domain/src/main/java/com/everymeal/domain/repository/review/ReviewRepository.kt +++ b/domain/src/main/java/com/everymeal/domain/repository/review/ReviewRepository.kt @@ -4,8 +4,6 @@ import com.everymeal.domain.model.review.Review import com.everymeal.domain.model.review.UserReview interface ReviewRepository { - suspend fun putReview(reviewIdx: Int, userReview: UserReview): Result - suspend fun deleteReview(reviewIdx: Int): Result suspend fun getReviewList(cursorIdx: Int, mealIdx: Int, pageSize: Int): Result suspend fun postReview(userReview: UserReview): Result } diff --git a/domain/src/test/java/com/everymeal/domain/ExampleUnitTest.kt b/domain/src/test/java/com/everymeal/domain/ExampleUnitTest.kt index 33996285..9448d257 100644 --- a/domain/src/test/java/com/everymeal/domain/ExampleUnitTest.kt +++ b/domain/src/test/java/com/everymeal/domain/ExampleUnitTest.kt @@ -1,9 +1,8 @@ package com.everymeal.domain +import org.junit.Assert.assertEquals import org.junit.Test -import org.junit.Assert.* - /** * Example local unit test, which will execute on the development machine (host). * @@ -14,4 +13,4 @@ class ExampleUnitTest { fun addition_isCorrect() { assertEquals(4, 2 + 2) } -} \ No newline at end of file +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f788ebfa..87c0b7be 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,7 @@ [versions] agp = "8.1.1" coil-compose = "2.4.0" +junit-jupiter = "5.8.1" kotlin = "1.8.21" core-ktx = "1.12.0" junit = "4.13.2" @@ -12,6 +13,7 @@ compose-bom = "2023.10.01" dagger-hilt = "2.46.1" hilt-compose = "1.0.0" okhttp = "4.11.0" +paging-common = "3.2.0-rc01" retrofit = "2.9.0" serialization = "1.6.0" kotlin-serilization = "1.0.0" @@ -27,11 +29,13 @@ paging-runtime = "3.1.0" [libraries] agp = { module = "com.android.tools.build:gradle", version.ref = "agp" } +androidx-paging-common-v320rc01 = { module = "androidx.paging:paging-common", version.ref = "paging-common" } coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coil-compose" } core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "core-ktx" } junit = { group = "junit", name = "junit", version.ref = "junit" } androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-ext-junit" } espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso-core" } +junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" } lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycle-runtime-ktx" } activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activity" } activity = { group = "androidx.activity", name = "activity", version.ref = "activity" } diff --git a/presentation/src/main/java/com/everymeal/presentation/components/EveryMealRestaurantItem.kt b/presentation/src/main/java/com/everymeal/presentation/components/EveryMealRestaurantItem.kt index 796496e1..2f6599d1 100644 --- a/presentation/src/main/java/com/everymeal/presentation/components/EveryMealRestaurantItem.kt +++ b/presentation/src/main/java/com/everymeal/presentation/components/EveryMealRestaurantItem.kt @@ -32,7 +32,6 @@ import androidx.compose.ui.unit.sp import coil.compose.AsyncImage import com.everymeal.domain.model.restaurant.RestaurantDataEntity import com.everymeal.presentation.R -import com.everymeal.presentation.ui.home.HomeScreen import com.everymeal.presentation.ui.theme.EveryMeal_AndroidTheme import com.everymeal.presentation.ui.theme.Gray300 import com.everymeal.presentation.ui.theme.Gray500 @@ -50,12 +49,12 @@ fun EveryMealRestaurantItem( .fillMaxSize() .clickable( indication = null, - interactionSource = remember { MutableInteractionSource() } + interactionSource = remember { MutableInteractionSource() }, ) { onDetailClick() } .padding(horizontal = 20.dp) - .background(color = Color.White) + .background(color = Color.White), ) { RestaurantTitle(Modifier.fillMaxWidth(), restaurant) { onLoveClick() @@ -81,7 +80,7 @@ fun RestaurantTitle( color = Color.Black, fontSize = 17.sp, fontWeight = FontWeight.SemiBold, - maxLines = 1 + maxLines = 1, ) Text( modifier = Modifier @@ -91,7 +90,7 @@ fun RestaurantTitle( .padding(vertical = 3.dp, horizontal = 6.dp), text = restaurant.categoryDetail, color = Gray600, - fontSize = 12.sp + fontSize = 12.sp, ) Spacer(modifier = Modifier.weight(1f)) RestaurantLoveCount(restaurant, onLoveClick) @@ -106,7 +105,7 @@ fun RestaurantLoveCount( Column( modifier = Modifier.clickable( indication = null, - interactionSource = remember { MutableInteractionSource() } + interactionSource = remember { MutableInteractionSource() }, ) { onLoveClick() }, horizontalAlignment = Alignment.CenterHorizontally, ) { @@ -157,7 +156,7 @@ fun RestaurantRating(restaurant: RestaurantDataEntity) { fun RestaurantImage(restaurant: RestaurantDataEntity) { Row( modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, ) { restaurant.images?.let { when { @@ -169,9 +168,9 @@ fun RestaurantImage(restaurant: RestaurantDataEntity) { .aspectRatio(1f) .clip(RoundedCornerShape(8.dp)), model = image, - contentDescription = null + contentDescription = null, ) - if(index != 2) { + if (index != 2) { Spacer(modifier = Modifier.padding(end = 6.dp)) } } @@ -185,9 +184,9 @@ fun RestaurantImage(restaurant: RestaurantDataEntity) { .aspectRatio(1f) .clip(RoundedCornerShape(8.dp)), model = image, - contentDescription = null + contentDescription = null, ) - if(index != 1) { + if (index != 1) { Spacer(modifier = Modifier.padding(end = 6.dp)) } } @@ -201,11 +200,12 @@ fun RestaurantImage(restaurant: RestaurantDataEntity) { .aspectRatio(1f) .clip(RoundedCornerShape(8.dp)), model = restaurant.images!![0], - contentDescription = null + contentDescription = null, ) - Spacer(modifier = Modifier - .weight(2f) - .padding(end = 6.dp) + Spacer( + modifier = Modifier + .weight(2f) + .padding(end = 6.dp), ) } @@ -216,7 +216,7 @@ fun RestaurantImage(restaurant: RestaurantDataEntity) { .aspectRatio(1f) .clip(RoundedCornerShape(8.dp)), model = restaurant.images!![0], - contentDescription = null + contentDescription = null, ) Spacer(modifier = Modifier.padding(end = 6.dp)) AsyncImage( @@ -225,32 +225,32 @@ fun RestaurantImage(restaurant: RestaurantDataEntity) { .aspectRatio(1f) .clip(RoundedCornerShape(8.dp)), model = restaurant.images!![0], - contentDescription = null + contentDescription = null, ) Spacer(modifier = Modifier.padding(end = 6.dp)) Box( modifier = Modifier .weight(1f) - .aspectRatio(1f) + .aspectRatio(1f), ) { AsyncImage( modifier = Modifier .aspectRatio(1f) .fillMaxSize(), model = restaurant.images!![0], - contentDescription = null + contentDescription = null, ) Box( modifier = Modifier .matchParentSize() .clip(RoundedCornerShape(8.dp)) .background(Color.Black.copy(alpha = 0.2f)), - contentAlignment = Alignment.Center + contentAlignment = Alignment.Center, ) { Text( text = "+${restaurant.reviewCount - 2}", color = Color.White, - fontSize = 14.sp + fontSize = 14.sp, ) } } @@ -264,9 +264,5 @@ fun RestaurantImage(restaurant: RestaurantDataEntity) { @Composable fun HomeScreenPreview() { EveryMeal_AndroidTheme { - HomeScreen( - onDetailScreenClickType = {}, - onDetailRestaurantClick = {}, - ) } } diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/bottom/BottomNavigation.kt b/presentation/src/main/java/com/everymeal/presentation/ui/bottom/BottomNavigation.kt index 3a54c5ba..ca0fff57 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/bottom/BottomNavigation.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/bottom/BottomNavigation.kt @@ -33,10 +33,12 @@ enum class BottomNavigation( enum class EveryMealRoute(val route: String) { HOME("home"), + SEARCH("search"), UNIV_FOOD("univ-food"), WHAT_FOOD("what-food"), MY_PAGE("my-page"), DETAIL_LIST("detail-list"), DETAIL_RESTAURANT("detail-restaurant"), SCHOOL_AUTH("school-auth"), + REVIEW_SEARCH("review-search"), } diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListScreen.kt index 6c516a5f..3ddb83d1 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListScreen.kt @@ -1,10 +1,8 @@ package com.everymeal.presentation.ui.detail import androidx.compose.foundation.Image -import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize @@ -22,7 +20,6 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember 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.graphics.vector.ImageVector import androidx.compose.ui.res.vectorResource @@ -45,7 +42,6 @@ import com.everymeal.presentation.ui.theme.Grey2 import com.everymeal.presentation.ui.theme.Grey7 import com.everymeal.presentation.ui.theme.Main100 import com.everymeal.presentation.ui.theme.SubMain100 -import com.everymeal.presentation.ui.theme.Typography @Composable fun DetailListScreen( @@ -55,68 +51,113 @@ fun DetailListScreen( ) { val detailListViewState by detailListViewModel.viewState.collectAsState() - val pagingRestaurantList : LazyPagingItems = detailListViewModel.restaurantItems.collectAsLazyPagingItems() + val pagingRestaurantList: LazyPagingItems = + detailListViewModel.restaurantItems.collectAsLazyPagingItems() LaunchedEffect(Unit) { detailListViewModel.setEvent(DetailContract.DetailEvent.InitDetailScreen) } - if(detailListViewState.sortBottomSheetState) { + if (detailListViewState.sortBottomSheetState) { EveryMealSortCategoryBottomSheetDialog( detailListViewState.detailSortCategoryType.title(), onClick = { - detailListViewModel.setEvent(DetailContract.DetailEvent.OnClickDetailListCategoryType(it.DetailSortCategoryType())) - detailListViewModel.setEvent(DetailContract.DetailEvent.SortBottomSheetStateChange(false)) + detailListViewModel.setEvent( + DetailContract.DetailEvent.OnClickDetailListCategoryType( + it.DetailSortCategoryType(), + ), + ) + detailListViewModel.setEvent( + DetailContract.DetailEvent.SortBottomSheetStateChange( + false, + ), + ) }, onDismiss = { - detailListViewModel.setEvent(DetailContract.DetailEvent.SortBottomSheetStateChange(false)) - } + detailListViewModel.setEvent( + DetailContract.DetailEvent.SortBottomSheetStateChange( + false, + ), + ) + }, ) } - if(detailListViewState.mealRatingBottomSheetState) { + if (detailListViewState.mealRatingBottomSheetState) { EveryMealCategoryRatingBottomSheetDialog( detailListViewState.rating, detailListViewState.restaurantCategoryType.title(), onClick = { - detailListViewModel.setEvent(DetailContract.DetailEvent.MealRatingBottomSheetStateChange(false)) + detailListViewModel.setEvent( + DetailContract.DetailEvent.MealRatingBottomSheetStateChange( + false, + ), + ) }, onDismiss = { - detailListViewModel.setEvent(DetailContract.DetailEvent.MealRatingBottomSheetStateChange(false)) + detailListViewModel.setEvent( + DetailContract.DetailEvent.MealRatingBottomSheetStateChange( + false, + ), + ) }, onCategoryClick = { - detailListViewModel.setEvent(DetailContract.DetailEvent.OnClickRestaurantCategoryType(it.RestaurantCategoryType())) + detailListViewModel.setEvent( + DetailContract.DetailEvent.OnClickRestaurantCategoryType( + it.RestaurantCategoryType(), + ), + ) }, onRatingClick = { detailListViewModel.setEvent(DetailContract.DetailEvent.OnClickRating(it)) - } + }, ) } - if(detailListViewState.reportBottomSheetState) { + if (detailListViewState.reportBottomSheetState) { EveryMealReportBottomSheetDialog( onClick = { - detailListViewModel.setEvent(DetailContract.DetailEvent.ReportBottomSheetStateChange(false)) - detailListViewModel.setEvent(DetailContract.DetailEvent.DetailReportBottomSheetStateChange(true)) + detailListViewModel.setEvent( + DetailContract.DetailEvent.ReportBottomSheetStateChange( + false, + ), + ) + detailListViewModel.setEvent( + DetailContract.DetailEvent.DetailReportBottomSheetStateChange( + true, + ), + ) }, onDismiss = { - detailListViewModel.setEvent(DetailContract.DetailEvent.ReportBottomSheetStateChange(false)) - } + detailListViewModel.setEvent( + DetailContract.DetailEvent.ReportBottomSheetStateChange( + false, + ), + ) + }, ) } - if(detailListViewState.detailReportBottomSheetState) { + if (detailListViewState.detailReportBottomSheetState) { EveryMealDetailReportBottomSheetDialog( detailListViewState.reportCategoryType.title(), onClick = { - detailListViewModel.setEvent(DetailContract.DetailEvent.DetailReportBottomSheetStateChange(false)) + detailListViewModel.setEvent( + DetailContract.DetailEvent.DetailReportBottomSheetStateChange( + false, + ), + ) }, onDismiss = { - detailListViewModel.setEvent(DetailContract.DetailEvent.DetailReportBottomSheetStateChange(false)) + detailListViewModel.setEvent( + DetailContract.DetailEvent.DetailReportBottomSheetStateChange( + false, + ), + ) }, onReportCategoryClick = { detailListViewModel.setEvent(DetailContract.DetailEvent.OnClickReportCategoryType(it.ReportCategoryType())) - } + }, ) } @@ -125,33 +166,41 @@ fun DetailListScreen( SaveTopBar(title = title) { navigateToPreviousScreen() } - } + }, ) { innerPadding -> LazyColumn( - modifier = Modifier.padding(innerPadding) + modifier = Modifier.padding(innerPadding), ) { item { Spacer(modifier = Modifier.padding(8.dp)) Row( modifier = Modifier .fillMaxSize() - .padding(horizontal = 20.dp) + .padding(horizontal = 20.dp), ) { DetailScreenChip( title = detailListViewState.detailSortCategoryType.title(), onChipClicked = { - detailListViewModel.setEvent(DetailContract.DetailEvent.SortBottomSheetStateChange(true)) - } + detailListViewModel.setEvent( + DetailContract.DetailEvent.SortBottomSheetStateChange( + true, + ), + ) + }, ) Spacer(modifier = Modifier.padding(4.dp)) DetailScreenChip( title = "필터", onChipClicked = { - detailListViewModel.setEvent(DetailContract.DetailEvent.MealRatingBottomSheetStateChange(true)) + detailListViewModel.setEvent( + DetailContract.DetailEvent.MealRatingBottomSheetStateChange( + true, + ), + ) }, - detailListViewState = detailListViewState + detailListViewState = detailListViewState, ) - if(detailListViewState.restaurantCategoryType.title().isNotEmpty()) { + if (detailListViewState.restaurantCategoryType.title().isNotEmpty()) { Spacer(modifier = Modifier.padding(4.dp)) DetailScreenChip( title = detailListViewState.restaurantCategoryType.title(), @@ -159,10 +208,10 @@ fun DetailListScreen( onChipClicked = { detailListViewModel.setEvent(DetailContract.DetailEvent.OnDeleteClickRestaurantCategoryType) }, - detailListViewState = detailListViewState + detailListViewState = detailListViewState, ) } - if(detailListViewState.rating != 0) { + if (detailListViewState.rating != 0) { Spacer(modifier = Modifier.padding(4.dp)) DetailScreenChip( title = "${detailListViewState.rating}", @@ -171,7 +220,7 @@ fun DetailListScreen( onChipClicked = { detailListViewModel.setEvent(DetailContract.DetailEvent.OnDeleteClickRating) }, - detailListViewState = detailListViewState + detailListViewState = detailListViewState, ) } // DetailScreenChip( @@ -204,7 +253,7 @@ fun DetailScreenChip( isCategory: Boolean = true, isRating: Boolean = false, onChipClicked: () -> Unit, - detailListViewState: DetailContract.DetailState? = null + detailListViewState: DetailContract.DetailState? = null, ) { val isRatingOrCategory = detailListViewState?.let { it.rating != 0 || it.restaurantCategoryType.name != "NONE" @@ -213,7 +262,7 @@ fun DetailScreenChip( Surface( modifier = Modifier.clickable( indication = null, - interactionSource = remember { MutableInteractionSource() } + interactionSource = remember { MutableInteractionSource() }, ) { onChipClicked() }, color = when { detailListViewState == null -> Grey2 @@ -223,16 +272,16 @@ fun DetailScreenChip( shape = RoundedCornerShape(100.dp), ) { Row( - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { - if(isRating) { + if (isRating) { Image( modifier = Modifier .padding(start = 12.dp, top = 8.dp, bottom = 8.dp) .size(16.dp), imageVector = ImageVector.vectorResource(id = R.drawable.icon_gray_star_mono), contentDescription = "gray_star", - colorFilter = ColorFilter.tint(Main100) + colorFilter = ColorFilter.tint(Main100), ) } Text( @@ -243,10 +292,15 @@ fun DetailScreenChip( else -> Grey7 }, fontSize = 14.sp, - modifier = Modifier.padding(start = if(!isRating) 12.dp else 4.dp, end = 4.dp, top = 6.dp, bottom = 6.dp), - fontWeight = FontWeight.SemiBold + modifier = Modifier.padding( + start = if (!isRating) 12.dp else 4.dp, + end = 4.dp, + top = 6.dp, + bottom = 6.dp, + ), + fontWeight = FontWeight.SemiBold, ) - if(isCategory) { + if (isCategory) { Image( modifier = Modifier .padding(end = 12.dp) @@ -257,7 +311,7 @@ fun DetailScreenChip( detailListViewState == null -> ColorFilter.tint(Grey7) isRatingOrCategory -> ColorFilter.tint(Main100) else -> ColorFilter.tint(Grey7) - } + }, ) } else { Image( @@ -265,7 +319,7 @@ fun DetailScreenChip( .padding(end = 12.dp) .size(12.dp), imageVector = ImageVector.vectorResource(id = R.drawable.icon_x_mono_12), - contentDescription = "close" + contentDescription = "close", ) } } @@ -276,7 +330,6 @@ fun DetailScreenChip( @Composable fun PreviewDetailListScreen() { DetailListScreen(title = "맛집") { - } } @@ -287,7 +340,6 @@ fun PreviewDetailScreenChip() { title = "최신순", isCategory = true, onChipClicked = { - - } + }, ) -} \ No newline at end of file +} diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeContract.kt b/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeContract.kt index dadf9ac0..05ec51e4 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeContract.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeContract.kt @@ -9,7 +9,7 @@ class HomeContract { data class HomeState( val uiState: LoadState = LoadState.SUCCESS, val detailListScreenType: DetailListScreenType = DetailListScreenType.RECOMMEND, - val bottomSheetState: Boolean = false + val bottomSheetState: Boolean = false, ) : ViewState sealed class HomeEvent : ViewEvent { @@ -18,7 +18,8 @@ class HomeContract { } sealed class HomeEffect : ViewSideEffect { - data class NavigateToDetailListScreen(val detailListScreenType: DetailListScreenType) : HomeEffect() + data class NavigateToDetailListScreen(val detailListScreenType: DetailListScreenType) : + HomeEffect() } } @@ -26,7 +27,7 @@ enum class DetailListScreenType { RECOMMEND, RESTAURANT, CAFE, - DRINK + DRINK, } fun String.DetailListScreenType(): DetailListScreenType { @@ -46,4 +47,4 @@ fun DetailListScreenType.title(): String { DetailListScreenType.CAFE -> "카페" DetailListScreenType.DRINK -> "술집" } -} \ No newline at end of file +} diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeScreen.kt index 6662bd01..4c188df3 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeScreen.kt @@ -55,9 +55,10 @@ import com.everymeal.presentation.ui.theme.Paddings @Composable fun HomeScreen( - homeViewModel : HomeViewModel = hiltViewModel(), - onDetailScreenClickType : (String) -> Unit, - onDetailRestaurantClick : () -> Unit, + homeViewModel: HomeViewModel = hiltViewModel(), + onDetailScreenClickType: (String) -> Unit, + onDetailRestaurantClick: () -> Unit, + onReviewBottomSheetClick: () -> Unit, ) { val items = listOf( RestaurantDataEntity( @@ -105,11 +106,11 @@ fun HomeScreen( title = stringResource(id = R.string.univ_admin_review_title), content = stringResource(id = R.string.univ_admin_review_content), onClick = { - + onReviewBottomSheetClick() }, onDismiss = { homeViewModel.setEvent(HomeContract.HomeEvent.BottomSheetStateChange(false)) - } + }, ) } @@ -172,11 +173,10 @@ fun HomeScreen( EveryMealRestaurantItem( item, onLoveClick = { - }, onDetailClick = { onDetailRestaurantClick() - } + }, ) Spacer(modifier = Modifier.padding(10.dp)) if (index != items.size - 1) { @@ -192,7 +192,6 @@ fun HomeScreen( EveryMealLineButton( text = stringResource(R.string.home_restaurant_button_text), onClick = { - }, ) } @@ -208,7 +207,6 @@ fun HomeScreen( items(reviewTestItem.size) { index -> val item = reviewTestItem[index] EveryMealReviewItem(item) { - } Spacer(modifier = Modifier.padding(10.dp)) if (index != reviewTestItem.size - 1) { @@ -224,7 +222,6 @@ fun HomeScreen( EveryMealLineButton( text = stringResource(R.string.home_restaurant_review_button_text), onClick = { - }, ) } @@ -256,7 +253,6 @@ fun HomeTopAppBar() { actions = { IconButton( onClick = { - }, ) { Icon( @@ -266,7 +262,6 @@ fun HomeTopAppBar() { } IconButton( onClick = { - }, ) { Icon( @@ -292,7 +287,7 @@ fun HomeMainTopLayout( .background(Gray300, RoundedCornerShape(12.dp)) .clickable( indication = null, - interactionSource = remember { MutableInteractionSource() } + interactionSource = remember { MutableInteractionSource() }, ) { onClick() } @@ -310,29 +305,29 @@ fun HomeMainTopLayout( text = stringResource(id = R.string.home_top_category_title, "슈니"), fontSize = 15.sp, style = EveryMealTypo.displaySmall, - color = Gray800 + color = Gray800, ) Text( text = stringResource(R.string.home_top_category_sub_title), style = EveryMealTypo.labelSmall, fontSize = 14.sp, - color = Gray500 + color = Gray500, ) } Spacer(modifier = Modifier.weight(1f)) Icon( imageVector = ImageVector.vectorResource(R.drawable.icon_arrow_right), contentDescription = stringResource(R.string.icon_arrow_right), - tint = Gray500 + tint = Gray500, ) } } @Composable fun HomeCategoryList( - isBottomSheet : Boolean = false, + isBottomSheet: Boolean = false, restaurantCategoryType: String = "", - onClick: (String) -> Unit + onClick: (String) -> Unit, ) { val horizotalDp = if (isBottomSheet) 0.dp else 20.dp @@ -340,13 +335,13 @@ fun HomeCategoryList( modifier = Modifier .fillMaxWidth() .padding(horizontal = horizotalDp), - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, ) { CategoryItem( isBottomSheet, restaurantCategoryType, R.drawable.ic_homemenu_recommend, - R.string.home_top_category_recommend + R.string.home_top_category_recommend, ) { onClick("추천") } @@ -354,7 +349,7 @@ fun HomeCategoryList( isBottomSheet, restaurantCategoryType, R.drawable.ic_homemenu_bap, - R.string.home_top_category_rice + R.string.home_top_category_rice, ) { onClick("밥집") } @@ -362,7 +357,7 @@ fun HomeCategoryList( isBottomSheet, restaurantCategoryType, R.drawable.ic_homemenu_cake, - R.string.home_top_category_cafe + R.string.home_top_category_cafe, ) { onClick("카페") } @@ -370,7 +365,7 @@ fun HomeCategoryList( isBottomSheet, restaurantCategoryType, R.drawable.ic_homemenu_beer, - R.string.home_top_category_drink + R.string.home_top_category_drink, ) { onClick("술집") } @@ -383,7 +378,7 @@ fun HomeDivider() { modifier = Modifier .fillMaxWidth() .background(color = Gray100) - .height(12.dp) + .height(12.dp), ) } @@ -418,7 +413,8 @@ fun CategoryItem( restaurantCategoryType == stringResource(categoryText) -> Gray100 else -> Color.White }, - RoundedCornerShape(12.dp)) + RoundedCornerShape(12.dp), + ) .padding(horizontal = 17.dp, vertical = 4.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { @@ -429,7 +425,7 @@ fun CategoryItem( Text( text = stringResource(categoryText), fontSize = 12.sp, - color = Color.Black + color = Color.Black, ) } } @@ -442,6 +438,7 @@ fun HomeScreenPreview() { HomeScreen( onDetailScreenClickType = {}, onDetailRestaurantClick = {}, + onReviewBottomSheetClick = {}, ) } } diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeViewModel.kt b/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeViewModel.kt index ab07f8cb..035d94c9 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeViewModel.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeViewModel.kt @@ -2,8 +2,8 @@ package com.everymeal.presentation.ui.home import com.everymeal.presentation.base.BaseViewModel import com.everymeal.presentation.ui.home.HomeContract.HomeEffect -import com.everymeal.presentation.ui.home.HomeContract.HomeState import com.everymeal.presentation.ui.home.HomeContract.HomeEvent +import com.everymeal.presentation.ui.home.HomeContract.HomeState import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject @@ -15,7 +15,7 @@ data class Review( val rating: Int, val reviewDate: String, val content: String, - val restaurantName: String + val restaurantName: String, ) data class Restaurant( @@ -28,10 +28,8 @@ data class Restaurant( ) @HiltViewModel -class HomeViewModel @Inject constructor( - -): BaseViewModel( - HomeState() +class HomeViewModel @Inject constructor() : BaseViewModel( + HomeState(), ) { override fun handleEvents(event: HomeEvent) { @@ -39,13 +37,14 @@ class HomeViewModel @Inject constructor( is HomeEvent.OnClickDetailList -> { sendEffect({ HomeEffect.NavigateToDetailListScreen(event.detailListScreenType) }) } + is HomeEvent.BottomSheetStateChange -> { updateState { copy( - bottomSheetState = event.bottomSheetState + bottomSheetState = event.bottomSheetState, ) } } } } -} \ No newline at end of file +} diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/main/MainScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/main/MainScreen.kt index c7e25d83..a0774f9e 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/main/MainScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/main/MainScreen.kt @@ -21,6 +21,8 @@ import com.everymeal.presentation.ui.detail.DetailListScreen import com.everymeal.presentation.ui.home.HomeScreen import com.everymeal.presentation.ui.mypage.MyPageScreen import com.everymeal.presentation.ui.restaurant.DetailRestaurantScreen +import com.everymeal.presentation.ui.review.search.ReviewSearchScreen +import com.everymeal.presentation.ui.search.SearchScreen import com.everymeal.presentation.ui.signup.school.SchoolAuthScreen import com.everymeal.presentation.ui.univfood.UnivFoodScreen import com.everymeal.presentation.ui.whatfood.WhatFoodScreen @@ -45,10 +47,10 @@ fun MainScreen( navController = navController, navigationItem = navigationItem, ) - } + }, ) } - } + }, ) { padding -> NavHost( modifier = Modifier.padding(padding), @@ -62,7 +64,10 @@ fun MainScreen( }, onDetailRestaurantClick = { navController.navigate(EveryMealRoute.SCHOOL_AUTH.route) - } + }, + onReviewBottomSheetClick = { + navController.navigate(EveryMealRoute.REVIEW_SEARCH.route) + }, ) } composable(route = EveryMealRoute.UNIV_FOOD.route) { @@ -78,7 +83,7 @@ fun MainScreen( val detailScreenType = it.arguments?.getString(DETAIL_SCREEN_TYPE) ?: "" DetailListScreen( title = detailScreenType, - navigateToPreviousScreen = { navController.popBackStack() } + navigateToPreviousScreen = { navController.popBackStack() }, ) } composable(route = EveryMealRoute.DETAIL_RESTAURANT.route) { @@ -88,9 +93,15 @@ fun MainScreen( SchoolAuthScreen( onSuccessEmailVerification = { navController.popBackStack() - } + }, ) } + composable(route = EveryMealRoute.REVIEW_SEARCH.route) { + ReviewSearchScreen(navController = navController) + } + composable(route = EveryMealRoute.SEARCH.route) { + SearchScreen(navController = navController) + } } } diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreen.kt index 3b13f0ef..4767bac6 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreen.kt @@ -49,13 +49,12 @@ import com.everymeal.presentation.ui.theme.Grey2 import com.everymeal.presentation.ui.theme.Grey9 import com.everymeal.presentation.ui.theme.Typography - @Composable fun ReviewScreen( - viewModel: ReviewScreenViewModel = hiltViewModel() + viewModel: ReviewScreenViewModel = hiltViewModel(), ) { val pickMultipleMedia = rememberLauncherForActivityResult( - ActivityResultContracts.PickMultipleVisualMedia(10) + ActivityResultContracts.PickMultipleVisualMedia(10), ) { viewModel.setEvent(ReviewEvent.OnImageSelected(it)) Log.d("ReviewScreen", "ReviewScreen: $it") @@ -66,12 +65,10 @@ fun ReviewScreen( topBar = { ReviewTopBar( title = stringResource(R.string.review_write), - onBackClicked = { - - }, + onBackClicked = {}, ) }, - containerColor = Color.White + containerColor = Color.White, ) { innerPadding -> Box(modifier = Modifier.padding(innerPadding)) { Column { @@ -99,26 +96,29 @@ fun ReviewScreen( viewModel.setEvent(ReviewEvent.OnReviewTextChanged(it)) }, onReviewRegisterClicked = { - viewModel.setEvent(ReviewEvent.PostReview( - reviewValue = viewState.reviewValue, - imageUri = viewState.imageUri, - restaurantType = viewState.restaurantType, - restaurantName = viewState.restaurantName, - starRatingCount = viewState.starRatingStateList.count { it.value } - )) + viewModel.setEvent( + ReviewEvent.PostReview( + mealIdx = viewState.idx, + reviewValue = viewState.reviewValue, + imageUri = viewState.imageUri, + restaurantType = viewState.restaurantType, + restaurantName = viewState.restaurantName, + starRatingCount = viewState.starRatingStateList.count { it.value }, + ), + ) Toast.makeText( context, context.getString(R.string.register_review), - Toast.LENGTH_SHORT + Toast.LENGTH_SHORT, ).show() }, onAddPhotoClicked = { pickMultipleMedia.launch( PickVisualMediaRequest( - ActivityResultContracts.PickVisualMedia.ImageOnly - ) + ActivityResultContracts.PickVisualMedia.ImageOnly, + ), ) - } + }, ) } } @@ -134,7 +134,7 @@ fun ColumnScope.StarDetail( Column( modifier = modifier .align(Alignment.CenterHorizontally) - .padding(top = 133.dp) + .padding(top = 133.dp), ) { RestaurantType( viewState = viewState, @@ -146,7 +146,7 @@ fun ColumnScope.StarDetail( modifier = Modifier .padding(top = 50.dp), ratingStateList = viewState.starRatingStateList, - starRatingClicked = startRatingClicked + starRatingClicked = startRatingClicked, ) } } @@ -161,7 +161,7 @@ fun ColumnScope.RestaurantType( .align(Alignment.CenterHorizontally) .background( color = Grey2, - shape = RoundedCornerShape(4.dp) + shape = RoundedCornerShape(4.dp), ) .padding(horizontal = 6.dp, vertical = 3.dp), text = viewState.restaurantType, @@ -177,7 +177,7 @@ fun ColumnScope.RestaurantType( @Composable fun RestaurantName( modifier: Modifier = Modifier, - viewState: ReviewState + viewState: ReviewState, ) { Text( modifier = modifier, @@ -191,21 +191,6 @@ fun RestaurantName( ) } -@Composable -fun ReviewSearchBar( - modifier: Modifier = Modifier, - searchBarClicked: () -> Unit -) { - SearchBar( - modifier = modifier.clickable { - searchBarClicked() - }, - searchQuery = "", - changeQuery = {}, - setShowHistory = {} - ) -} - @Composable fun StarRating( modifier: Modifier = Modifier, @@ -215,7 +200,7 @@ fun StarRating( ) { LazyRow( modifier = modifier, - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { itemsIndexed(ratingStateList) { index, active -> Image( @@ -227,44 +212,32 @@ fun StarRating( }, painter = if (active.value) { painterResource( - id = R.drawable.icon_active_star_mono + id = R.drawable.icon_active_star_mono, ) } else { painterResource( - id = R.drawable.icon_unactive_star_mono + id = R.drawable.icon_unactive_star_mono, ) }, - contentDescription = null + contentDescription = null, ) } } } -@Composable -fun ReviewGuideHeader( - modifier: Modifier = Modifier -) { - Text( - modifier = modifier - .padding(start = 24.dp, top = 48.dp), - text = stringResource(R.string.review_guide_header), - style = Typography.titleLarge, - ) -} - @OptIn(ExperimentalMaterial3Api::class) @Composable fun ReviewTopBar( modifier: Modifier = Modifier, title: String, - onBackClicked: () -> Unit + onBackClicked: () -> Unit, ) { TopAppBar( title = { Text( text = title, style = Typography.bodySmall, - color = Grey9 + color = Grey9, ) }, actions = { @@ -275,15 +248,15 @@ fun ReviewTopBar( .padding(end = 4.dp) .clickable(onClick = onBackClicked), painter = painterResource(id = R.drawable.icon_x_mono), - contentDescription = null + contentDescription = null, ) - } + }, ) } @Composable fun ReviewSaveDialog( - modifier: Modifier = Modifier + modifier: Modifier = Modifier, ) { val showDialog = remember { mutableStateOf(true) } if (showDialog.value) { @@ -299,7 +272,7 @@ fun ReviewSaveDialog( }, onDisMissClicked = { showDialog.value = false - } + }, ) } } diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreenContract.kt b/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreenContract.kt index d353f44f..4f9d8ea0 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreenContract.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreenContract.kt @@ -8,33 +8,35 @@ import com.everymeal.presentation.base.ViewSideEffect import com.everymeal.presentation.base.ViewState data class ReviewState( - var starRatingStateList: List> = listOf( + val starRatingStateList: List> = listOf( mutableStateOf(false), mutableStateOf(false), mutableStateOf(false), mutableStateOf(false), mutableStateOf(false), ), - var imageUri: List = listOf(), - var restaurantType: String = "주점", - var restaurantName: String = "성신 이자카야", - var reviewValue: String = "" + val imageUri: List = listOf(), + val idx: Int = 0, + val restaurantType: String = "주점", + val restaurantName: String = "성신 이자카야", + val reviewValue: String = "", ) : ViewState sealed class ReviewEvent : ViewEvent { data class OnStarClicked( - val starIndex: Int + val starIndex: Int, ) : ReviewEvent() data class OnReviewTextChanged( - val reviewValue: String + val reviewValue: String, ) : ReviewEvent() data class OnImageSelected( - val imageUri: List + val imageUri: List, ) : ReviewEvent() data class PostReview( + val mealIdx: Int, val reviewValue: String, val imageUri: List, val restaurantType: String, @@ -43,7 +45,4 @@ sealed class ReviewEvent : ViewEvent { ) : ReviewEvent() } -sealed class ReviewEffect : ViewSideEffect { - -} - +sealed class ReviewEffect : ViewSideEffect diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreenViewModel.kt b/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreenViewModel.kt index 2dea2b25..84ba725e 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreenViewModel.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreenViewModel.kt @@ -11,7 +11,7 @@ import javax.inject.Inject @HiltViewModel class ReviewScreenViewModel @Inject constructor( - private val postReviewUseCase: PostReviewUseCase + private val postReviewUseCase: PostReviewUseCase, ) : BaseViewModel(ReviewState()) { override fun handleEvents(event: ReviewEvent) { when (event) { @@ -21,7 +21,7 @@ class ReviewScreenViewModel @Inject constructor( mutableStateOf(index <= event.starIndex) } copy( - starRatingStateList = newStarRatingStateList + starRatingStateList = newStarRatingStateList, ) } } @@ -29,7 +29,7 @@ class ReviewScreenViewModel @Inject constructor( is ReviewEvent.OnReviewTextChanged -> { updateState { copy( - reviewValue = event.reviewValue + reviewValue = event.reviewValue, ) } } @@ -37,7 +37,7 @@ class ReviewScreenViewModel @Inject constructor( is ReviewEvent.OnImageSelected -> { updateState { copy( - imageUri = event.imageUri + imageUri = event.imageUri, ) } } @@ -45,14 +45,13 @@ class ReviewScreenViewModel @Inject constructor( is ReviewEvent.PostReview -> { viewModelScope.launch { val userReview = UserReview( - mealIdx = event.mealIdx, + idx = event.mealIdx, grade = event.starRatingCount, content = event.reviewValue, - imageList = event.imageUri.map { it.toString() } + imageList = event.imageUri.map { it.toString() }, ) postReviewUseCase(userReview) } - } } } diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/review/detail/ReviewDetailScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/review/detail/ReviewDetailScreen.kt index 817c1fab..7eeeb274 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/review/detail/ReviewDetailScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/review/detail/ReviewDetailScreen.kt @@ -1,9 +1,6 @@ package com.everymeal.presentation.ui.review.detail import androidx.compose.foundation.Image -import androidx.compose.foundation.gestures.Orientation -import androidx.compose.foundation.gestures.rememberScrollableState -import androidx.compose.foundation.gestures.scrollable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -45,7 +42,7 @@ fun ReviewDetailScreen() { mutableStateOf(true), mutableStateOf(true), mutableStateOf(true), - mutableStateOf(true) + mutableStateOf(true), ) } Scaffold( @@ -53,26 +50,25 @@ fun ReviewDetailScreen() { ReviewTopBar( title = stringResource(R.string.review_title), onBackClicked = { - }, ) - } + }, ) { innerPadding -> val scrollState = rememberScrollState() Column( modifier = Modifier .padding(innerPadding) - .verticalScroll(scrollState) + .verticalScroll(scrollState), ) { UserProfileAppbar( userName = "햄식이", - ratingList = mockRatingList + ratingList = mockRatingList, ) FoodImage( modifier = Modifier .fillMaxWidth() .aspectRatio(1f) - .padding(top = 24.dp) + .padding(top = 24.dp), ) ReviewText( modifier = Modifier.padding( @@ -88,13 +84,13 @@ fun ReviewDetailScreen() { private fun UserProfileAppbar( userName: String, userProfileUrl: String? = null, - ratingList: List> + ratingList: List>, ) { Row { Image( modifier = Modifier.size(40.dp), painter = painterResource(id = R.drawable.profile_ex_image), - contentDescription = "profile" + contentDescription = "profile", ) Column(modifier = Modifier.padding(start = 12.dp)) { Text( @@ -104,12 +100,12 @@ private fun UserProfileAppbar( color = Gray800, ) Row( - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { StarRating( modifier = Modifier.padding(horizontal = 1.dp), ratingStateList = ratingList, - starSize = 14.dp + starSize = 14.dp, ) // TODO 시간 계산 필요 Text( @@ -127,64 +123,64 @@ private fun UserProfileAppbar( .size(24.dp) .padding(end = 20.dp), painter = painterResource(id = R.drawable.icon_dots_mono), - contentDescription = "more" + contentDescription = "more", ) } } @Composable private fun FoodImage( - modifier: Modifier = Modifier + modifier: Modifier = Modifier, ) { Box( - modifier = modifier + modifier = modifier, ) { Image( modifier = Modifier.fillMaxSize(), painter = painterResource(id = R.drawable.food_ex_2), - contentDescription = "more" + contentDescription = "more", ) LocationButton( modifier = Modifier .align(Alignment.BottomStart) .padding( start = 16.dp, - bottom = 16.dp - ) + bottom = 16.dp, + ), ) PageInfo( modifier = Modifier .align(Alignment.BottomEnd) .padding( end = 16.dp, - bottom = 16.dp - ) + bottom = 16.dp, + ), ) } } @Composable private fun LocationButton( - modifier: Modifier = Modifier + modifier: Modifier = Modifier, ) { Surface( modifier = modifier, color = Color(0x99000000), - shape = RoundedCornerShape(size = 6.dp) + shape = RoundedCornerShape(size = 6.dp), ) { Row( modifier = Modifier.padding( horizontal = 6.dp, - vertical = 4.dp + vertical = 4.dp, ), - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Image( modifier = Modifier.size(16.dp), painter = painterResource( - id = R.drawable.icon_pin_location_mono + id = R.drawable.icon_pin_location_mono, ), - contentDescription = "location" + contentDescription = "location", ) Spacer(modifier = Modifier.padding(4.dp)) Text( @@ -196,7 +192,7 @@ private fun LocationButton( Image( modifier = Modifier.size(16.dp), painter = painterResource(id = R.drawable.icon_arrow_right), - contentDescription = null + contentDescription = null, ) } } @@ -204,17 +200,17 @@ private fun LocationButton( @Composable private fun PageInfo( - modifier: Modifier = Modifier + modifier: Modifier = Modifier, ) { Surface( modifier = modifier, color = Color(0x99000000), - shape = RoundedCornerShape(size = 20.dp) + shape = RoundedCornerShape(size = 20.dp), ) { Text( modifier = Modifier.padding( horizontal = 8.dp, - vertical = 2.dp + vertical = 2.dp, ), text = "1/3", fontSize = 14.sp, @@ -226,7 +222,7 @@ private fun PageInfo( @Composable fun ReviewText( - modifier: Modifier = Modifier + modifier: Modifier = Modifier, ) { Text( modifier = modifier, diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/review/search/ReviewSearchScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/review/search/ReviewSearchScreen.kt new file mode 100644 index 00000000..62b8e0b3 --- /dev/null +++ b/presentation/src/main/java/com/everymeal/presentation/ui/review/search/ReviewSearchScreen.kt @@ -0,0 +1,76 @@ +package com.everymeal.presentation.ui.review.search + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import androidx.navigation.NavController +import com.everymeal.presentation.R +import com.everymeal.presentation.ui.bottom.EveryMealRoute +import com.everymeal.presentation.ui.review.ReviewTopBar +import com.everymeal.presentation.ui.search.topbar.SearchBar +import com.everymeal.presentation.ui.theme.Typography + +@Composable +fun ReviewSearchScreen( + navController: NavController, +) { + Scaffold( + topBar = { + ReviewTopBar( + title = stringResource(R.string.review_write), + onBackClicked = { + navController.popBackStack() + }, + ) + }, + containerColor = Color.White, + ) { innerPadding -> + Box(modifier = Modifier.padding(innerPadding)) { + Column { + ReviewGuideHeader() + ReviewSearchBar( + modifier = Modifier + .padding(top = 28.dp) + .padding(horizontal = 20.dp), + searchBarClicked = { + navController.navigate(EveryMealRoute.SEARCH.route) + }, + ) + } + } + } +} + +@Composable +fun ReviewGuideHeader( + modifier: Modifier = Modifier, +) { + Text( + modifier = modifier + .padding(start = 24.dp, top = 48.dp), + text = stringResource(R.string.review_guide_header), + style = Typography.titleLarge, + ) +} + +@Composable +fun ReviewSearchBar( + modifier: Modifier = Modifier, + searchBarClicked: () -> Unit, +) { + SearchBar( + modifier = modifier.clickable { + searchBarClicked() + }, + searchQuery = "", + changeQuery = {}, + ) +} diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/review/write/ReviewWriteScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/review/write/ReviewWriteScreen.kt index 6712f348..8cc9fad9 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/review/write/ReviewWriteScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/review/write/ReviewWriteScreen.kt @@ -49,29 +49,29 @@ fun ReviewWriteScreen( starRatingClicked: (Int) -> Unit, reviewTextChanged: (String) -> Unit, onReviewRegisterClicked: () -> Unit, - onAddPhotoClicked: () -> Unit + onAddPhotoClicked: () -> Unit, ) { Column( modifier = modifier .fillMaxWidth() .background(color = Color.White) .padding(horizontal = 20.dp), - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, ) { RestaurantType( - viewState = viewState + viewState = viewState, ) RestaurantName( modifier = Modifier .padding(top = 12.dp), - viewState = viewState + viewState = viewState, ) StarRating( modifier = modifier.padding(top = 16.dp), ratingStateList = viewState.starRatingStateList, starRatingClicked = starRatingClicked, - starSize = 20.dp + starSize = 20.dp, ) Spacer(modifier = Modifier.height(60.dp)) EveryMealTextField( @@ -85,11 +85,11 @@ fun ReviewWriteScreen( Spacer(modifier = Modifier.height(16.dp)) Row( modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.Start + horizontalArrangement = Arrangement.Start, ) { AddReviewPhoto( viewState = viewState, - addPhotoClicked = onAddPhotoClicked + addPhotoClicked = onAddPhotoClicked, ) LazyRow { items(viewState.imageUri) { @@ -100,7 +100,7 @@ fun ReviewWriteScreen( .clip(RoundedCornerShape(10.dp)), model = it, contentScale = ContentScale.Crop, - contentDescription = null + contentDescription = null, ) } } @@ -110,7 +110,7 @@ fun ReviewWriteScreen( modifier = Modifier .fillMaxWidth() .height(54.dp), - onReviewRegisterClicked = onReviewRegisterClicked + onReviewRegisterClicked = onReviewRegisterClicked, ) Spacer(modifier = Modifier.height(20.dp)) } @@ -128,20 +128,20 @@ private fun AddReviewPhoto( .clickable { addPhotoClicked() }, border = BorderStroke( width = 1.dp, - color = Gray200 + color = Gray200, ), shape = RoundedCornerShape(10.dp), - color = Color.White + color = Color.White, ) { Column( modifier = Modifier, horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center + verticalArrangement = Arrangement.Center, ) { Image( modifier = Modifier.size(24.dp), painter = painterResource(id = R.drawable.icon_picture_mono), - contentDescription = null + contentDescription = null, ) Text( modifier = Modifier.padding(top = 2.dp), @@ -160,7 +160,7 @@ private fun AddReviewPhoto( @Composable private fun ReviewRegisterButton( modifier: Modifier = Modifier, - onReviewRegisterClicked: () -> Unit + onReviewRegisterClicked: () -> Unit, ) { Button( modifier = modifier, @@ -181,8 +181,8 @@ private fun ReviewRegisterButton( fontSize = 16.sp, fontWeight = FontWeight(500), color = Color.White, - ) + ), ) - } + }, ) } diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchContract.kt b/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchContract.kt index c8c79b37..66acfaef 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchContract.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchContract.kt @@ -1,10 +1,10 @@ package com.everymeal.presentation.ui.search +import com.everymeal.domain.model.restaurant.RestaurantDataEntity import com.everymeal.presentation.base.ViewEvent import com.everymeal.presentation.base.ViewSideEffect import com.everymeal.presentation.base.ViewState - /* 대학교 불러오기 LoadState 대학교 선택하기 State Hoisting @@ -13,24 +13,21 @@ data class SearchState( val searchQuery: String = "", val searchIsShowHistory: Boolean = true, val searchHistoryItems: List = listOf(), + val searchResultList: List = listOf(), ) : ViewState - sealed class SearchEvent : ViewEvent { - data class SetShowSearchHistory( - val show: Boolean - ) : SearchEvent() - data class SearchQueryChanged( - val query: String + val query: String, ) : SearchEvent() data class UpdateSearchHistory( - val historyItems: List + val historyItems: List, ) : SearchEvent() + data class SearchResultLoaded( + val searchResultList: List, + ) : SearchEvent() } -sealed class SearchEffect : ViewSideEffect { - -} +sealed class SearchEffect : ViewSideEffect diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchScreen.kt index 94aeaba7..c0ad0051 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchScreen.kt @@ -9,6 +9,8 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn 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.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -17,6 +19,7 @@ import androidx.compose.runtime.collectAsState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle @@ -25,30 +28,31 @@ 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.navigation.NavController +import com.everymeal.domain.model.restaurant.RestaurantDataEntity import com.everymeal.presentation.R +import com.everymeal.presentation.components.EveryMealRestaurantItem import com.everymeal.presentation.ui.search.history.SearchHistoryList -import com.everymeal.presentation.ui.search.topbar.TopBar +import com.everymeal.presentation.ui.search.topbar.SearchTopBar import com.everymeal.presentation.ui.theme.Gray800 @Composable fun SearchScreen( - viewModel: SearchViewModel = hiltViewModel() + navController: NavController, + viewModel: SearchViewModel = hiltViewModel(), ) { val viewState = viewModel.viewState.collectAsState() + Scaffold( topBar = { - TopBar( + SearchTopBar( onBackClick = { }, - setShowHistory = { viewModel.setEvent(SearchEvent.SetShowSearchHistory(it)) }, searchQuery = viewState.value.searchQuery, changeQuery = { viewModel.setEvent(SearchEvent.SearchQueryChanged(it)) }, ) }, - containerColor = Color.White + containerColor = Color.White, ) { innerPadding -> - SearchDetail( - modifier = Modifier.padding(innerPadding) - ) if (viewState.value.searchIsShowHistory) { SearchHistoryList( historyItems = viewState.value.searchHistoryItems, @@ -62,36 +66,48 @@ fun SearchScreen( modifier = Modifier .padding(innerPadding) .fillMaxWidth() - .padding(horizontal = 20.dp) + .padding(horizontal = 20.dp), ) } else { - EmptyView() + SearchDetail( + modifier = Modifier.padding(innerPadding), + searchResultList = viewState.value.searchResultList, + ) } } } @Composable fun SearchDetail( - modifier: Modifier = Modifier + modifier: Modifier = Modifier, + searchResultList: List, ) { - + LazyColumn(modifier = modifier) { + itemsIndexed(searchResultList) { index, restaurant -> + EveryMealRestaurantItem( + restaurant = restaurant, + onLoveClick = { }, + onDetailClick = { }, + ) + } + } } @Composable fun EmptyView( - modifier: Modifier = Modifier + modifier: Modifier = Modifier, ) { Box( modifier = modifier.fillMaxSize(), - contentAlignment = Alignment.Center + contentAlignment = Alignment.Center, ) { Column( - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, ) { Image( painter = painterResource(id = R.drawable.icon_store), contentDescription = null, - modifier = Modifier.size(40.dp) + modifier = Modifier.size(40.dp), ) Spacer(modifier = Modifier.heightIn(8.dp)) Text( @@ -99,8 +115,8 @@ fun EmptyView( style = TextStyle( color = Gray800, fontWeight = FontWeight(500), - fontSize = 15.sp - ) + fontSize = 15.sp, + ), ) } } @@ -109,7 +125,7 @@ fun EmptyView( private fun removeHistoryItem( viewState: State, removeItem: String, - viewModel: SearchViewModel + viewModel: SearchViewModel, ) { val historyItems = viewState.value.searchHistoryItems val removedHistoryItems = historyItems.filterNot { it == removeItem } @@ -119,5 +135,7 @@ private fun removeHistoryItem( @Preview @Composable fun PreviewSearchScreen() { - SearchScreen() + SearchScreen( + navController = NavController(LocalContext.current), + ) } diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchViewModel.kt b/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchViewModel.kt index 9dc6c7dd..7b674481 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchViewModel.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchViewModel.kt @@ -1,7 +1,9 @@ package com.everymeal.presentation.ui.search +import androidx.lifecycle.viewModelScope import com.everymeal.presentation.base.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel @@ -15,23 +17,36 @@ class SearchViewModel @Inject constructor() : override fun handleEvents(event: SearchEvent) { when (event) { - is SearchEvent.SetShowSearchHistory -> { + is SearchEvent.SearchQueryChanged -> { updateState { - copy(searchIsShowHistory = event.show) + copy( + searchQuery = event.query, + searchIsShowHistory = event.query.isEmpty(), + ) } } - is SearchEvent.SearchQueryChanged -> { + is SearchEvent.UpdateSearchHistory -> { updateState { - copy(searchQuery = event.query) + copy(searchHistoryItems = event.historyItems) } } + is SearchEvent.SearchResultLoaded -> { - is SearchEvent.UpdateSearchHistory -> { updateState { - copy(searchHistoryItems = event.historyItems) + copy( + searchResultList = event.searchResultList, + searchIsShowHistory = false, + ) } } } } + + private fun search() { + viewModelScope.launch { +// val result = repository.getUnivRestaurant(1, "test") +// setEvent(SearchEvent.SearchResultLoaded(result)) + } + } } diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/search/history/SearchHistoryList.kt b/presentation/src/main/java/com/everymeal/presentation/ui/search/history/SearchHistoryList.kt index ac7a4942..fa691ca5 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/search/history/SearchHistoryList.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/search/history/SearchHistoryList.kt @@ -14,7 +14,6 @@ import androidx.compose.material.icons.filled.Close import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle @@ -30,9 +29,8 @@ fun SearchHistoryList( isVisible: Boolean, onHistoryItemClicked: (String) -> Unit, removeHistoryItem: (String) -> Unit, - modifier: Modifier = Modifier + modifier: Modifier = Modifier, ) { - if (isVisible) { Column(modifier = modifier) { Text( @@ -44,21 +42,21 @@ fun SearchHistoryList( ), modifier = Modifier .fillMaxWidth() - .padding(top = 30.dp, bottom = 10.dp) + .padding(top = 30.dp, bottom = 10.dp), ) LazyColumn( - modifier = Modifier.fillMaxWidth() + modifier = Modifier.fillMaxWidth(), ) { items(historyItems) { item -> Row( modifier = Modifier .fillMaxWidth() .padding(vertical = 16.dp), - horizontalArrangement = Arrangement.SpaceBetween + horizontalArrangement = Arrangement.SpaceBetween, ) { Text( text = item, - modifier = Modifier.clickable { onHistoryItemClicked(item) } + modifier = Modifier.clickable { onHistoryItemClicked(item) }, ) Icon( imageVector = Icons.Default.Close, @@ -67,7 +65,7 @@ fun SearchHistoryList( .size(24.dp) .clickable { removeHistoryItem(item) - } + }, ) } } diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/search/topbar/SearchTopBar.kt b/presentation/src/main/java/com/everymeal/presentation/ui/search/topbar/SearchTopBar.kt index e277d7ab..2723584e 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/search/topbar/SearchTopBar.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/search/topbar/SearchTopBar.kt @@ -17,17 +17,16 @@ import com.everymeal.presentation.R import com.everymeal.presentation.components.EveryMealTextField @Composable -fun TopBar( +fun SearchTopBar( modifier: Modifier = Modifier, searchQuery: String, changeQuery: (String) -> Unit, onBackClick: () -> Unit, - setShowHistory: (Boolean) -> Unit, ) { Row( modifier = modifier .fillMaxWidth() - .padding(top = 14.dp) + .padding(top = 14.dp), ) { Image( painter = painterResource(id = R.drawable.ic_launcher_foreground), @@ -37,12 +36,11 @@ fun TopBar( .padding(12.dp) .clickable { onBackClick() - } + }, ) SearchBar( searchQuery = searchQuery, changeQuery = changeQuery, - setShowHistory = setShowHistory, ) } } @@ -52,7 +50,6 @@ fun SearchBar( modifier: Modifier = Modifier, searchQuery: String, changeQuery: (String) -> Unit, - setShowHistory: (Boolean) -> Unit ) { Box(modifier = modifier) { EveryMealTextField( @@ -62,13 +59,12 @@ fun SearchBar( value = searchQuery, onValueChange = { changeQuery(it) - setShowHistory(it.isEmpty()) }, placeholderText = stringResource(R.string.placeholder_search), leadingIcon = { Image( painter = painterResource(id = R.drawable.icon_search_mono), - contentDescription = null + contentDescription = null, ) }, ) From 07d4f35a2a69faed80a83ad194eef5985a050537 Mon Sep 17 00:00:00 2001 From: KwakEuiJin Date: Sun, 4 Feb 2024 14:31:14 +0900 Subject: [PATCH 3/9] =?UTF-8?q?[feat/review=5Fapi]:=20=EC=8B=9D=EB=8B=B9?= =?UTF-8?q?=20=EA=B2=80=EC=83=89=20api=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../restaruant/GetUnivRestaurantResponse.kt | 18 +-- .../restaruant/SearchRestaurantResponse.kt | 125 ++++++++++++++++++ .../restaurant/RestaurantRepositoryImpl.kt | 6 +- .../search/DefaultSearchRepository.kt | 17 +++ .../data/service/search/SearchService.kt | 13 ++ ...{RestaurantDataEntity.kt => Restaurant.kt} | 2 +- .../restaurant/RestaurantRepository.kt | 4 +- .../repository/search/SearchRepository.kt | 7 + .../restaurant/GetUnivRestaurantUseCase.kt | 6 +- .../components/EveryMealRestaurantItem.kt | 12 +- .../ui/bottom/BottomNavigation.kt | 10 +- .../ui/detail/DetailListScreen.kt | 4 +- .../ui/detail/DetailListViewModel.kt | 8 +- .../presentation/ui/home/HomeScreen.kt | 6 +- .../presentation/ui/search/SearchContract.kt | 8 +- .../presentation/ui/search/SearchScreen.kt | 7 +- .../presentation/ui/search/SearchViewModel.kt | 28 ++-- .../ui/search/topbar/SearchTopBar.kt | 14 +- 18 files changed, 232 insertions(+), 63 deletions(-) create mode 100644 data/src/main/java/com/everymeal/data/model/restaruant/SearchRestaurantResponse.kt create mode 100644 data/src/main/java/com/everymeal/data/repository/search/DefaultSearchRepository.kt create mode 100644 data/src/main/java/com/everymeal/data/service/search/SearchService.kt rename domain/src/main/java/com/everymeal/domain/model/restaurant/{RestaurantDataEntity.kt => Restaurant.kt} (91%) create mode 100644 domain/src/main/java/com/everymeal/domain/repository/search/SearchRepository.kt diff --git a/data/src/main/java/com/everymeal/data/model/restaruant/GetUnivRestaurantResponse.kt b/data/src/main/java/com/everymeal/data/model/restaruant/GetUnivRestaurantResponse.kt index f4801fe6..117f1342 100644 --- a/data/src/main/java/com/everymeal/data/model/restaruant/GetUnivRestaurantResponse.kt +++ b/data/src/main/java/com/everymeal/data/model/restaruant/GetUnivRestaurantResponse.kt @@ -1,6 +1,6 @@ package com.everymeal.data.model.restaruant -import com.everymeal.domain.model.restaurant.RestaurantDataEntity +import com.everymeal.domain.model.restaurant.Restaurant import kotlinx.serialization.Serializable @Serializable @@ -15,7 +15,7 @@ data class GetUnivRestaurantResponse( val sort: Sort, val numberOfElements: Int, val first: Boolean, - val empty: Boolean + val empty: Boolean, ) @Serializable @@ -30,7 +30,7 @@ data class RestaurantResponse( val reviewCount: Int, val recommendedCount: Int, val images: List?, - val isLiked: Boolean + val isLiked: Boolean, ) @Serializable @@ -40,18 +40,18 @@ data class Pageable( val pageNumber: Int, val pageSize: Int, val paged: Boolean, - val unpaged: Boolean + val unpaged: Boolean, ) @Serializable data class Sort( val empty: Boolean, val sorted: Boolean, - val unsorted: Boolean + val unsorted: Boolean, ) -fun RestaurantResponse.toEntity(): RestaurantDataEntity { - return RestaurantDataEntity( +fun RestaurantResponse.toEntity(): Restaurant { + return Restaurant( idx = this.idx, name = this.name, address = this.address, @@ -62,6 +62,6 @@ fun RestaurantResponse.toEntity(): RestaurantDataEntity { reviewCount = this.reviewCount, recommendedCount = this.recommendedCount, images = this.images, - isLiked = this.isLiked + isLiked = this.isLiked, ) -} \ No newline at end of file +} diff --git a/data/src/main/java/com/everymeal/data/model/restaruant/SearchRestaurantResponse.kt b/data/src/main/java/com/everymeal/data/model/restaruant/SearchRestaurantResponse.kt new file mode 100644 index 00000000..7dbd60a2 --- /dev/null +++ b/data/src/main/java/com/everymeal/data/model/restaruant/SearchRestaurantResponse.kt @@ -0,0 +1,125 @@ +package com.everymeal.data.model.restaruant + +import com.everymeal.domain.model.restaurant.Restaurant +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class SearchRestaurantResponse( + @SerialName("data") + val `data`: Data? = null, + @SerialName("localDateTime") + val localDateTime: String? = null, + @SerialName("message") + val message: String? = null, +) { + @Serializable + data class Data( + @SerialName("content") + val content: List? = null, + @SerialName("empty") + val empty: Boolean? = null, + @SerialName("first") + val first: Boolean? = null, + @SerialName("last") + val last: Boolean? = null, + @SerialName("number") + val number: Int? = null, + @SerialName("numberOfElements") + val numberOfElements: Int? = null, + @SerialName("pageable") + val pageable: Pageable? = null, + @SerialName("size") + val size: Int? = null, + @SerialName("sort") + val sort: Sort? = null, + @SerialName("totalElements") + val totalElements: Int? = null, + @SerialName("totalPages") + val totalPages: Int? = null, + ) { + @Serializable + data class Content( + @SerialName("address") + val address: String? = null, + @SerialName("categoryDetail") + val categoryDetail: String? = null, + @SerialName("distance") + val distance: Int? = null, + @SerialName("grade") + val grade: Int? = null, + @SerialName("idx") + val idx: Int? = null, + @SerialName("images") + val images: List? = null, + @SerialName("isLiked") + val isLiked: Boolean? = null, + @SerialName("name") + val name: String? = null, + @SerialName("phoneNumber") + val phoneNumber: String? = null, + @SerialName("recommendedCount") + val recommendedCount: Int? = null, + @SerialName("reviewCount") + val reviewCount: Int? = null, + ) + + @Serializable + data class Pageable( + @SerialName("offset") + val offset: Int? = null, + @SerialName("pageNumber") + val pageNumber: Int? = null, + @SerialName("pageSize") + val pageSize: Int? = null, + @SerialName("paged") + val paged: Boolean? = null, + @SerialName("sort") + val sort: Sort? = null, + @SerialName("unpaged") + val unpaged: Boolean? = null, + ) { + @Serializable + data class Sort( + @SerialName("empty") + val empty: Boolean? = null, + @SerialName("sorted") + val sorted: Boolean? = null, + @SerialName("unsorted") + val unsorted: Boolean? = null, + ) + } + + @Serializable + data class Sort( + @SerialName("empty") + val empty: Boolean? = null, + @SerialName("sorted") + val sorted: Boolean? = null, + @SerialName("unsorted") + val unsorted: Boolean? = null, + ) + } +} + + +fun SearchRestaurantResponse.toRestaurants(): List { + return this.data?.content?.mapNotNull { content -> + content?.let { + Restaurant( + idx = it.idx ?: 0, + name = it.name.orEmpty(), + address = it.address.orEmpty(), + phoneNumber = it.phoneNumber.orEmpty(), + categoryDetail = it.categoryDetail.orEmpty(), + distance = it.distance ?: 0, + grade = it.grade?.toFloat() + ?: 0f, + reviewCount = it.reviewCount ?: 0, + recommendedCount = it.recommendedCount ?: 0, + images = it.images?.filterNotNull(), + isLiked = it.isLiked ?: false, + ) + } + } ?: emptyList() +} diff --git a/data/src/main/java/com/everymeal/data/repository/restaurant/RestaurantRepositoryImpl.kt b/data/src/main/java/com/everymeal/data/repository/restaurant/RestaurantRepositoryImpl.kt index 56366a2e..01eee9e8 100644 --- a/data/src/main/java/com/everymeal/data/repository/restaurant/RestaurantRepositoryImpl.kt +++ b/data/src/main/java/com/everymeal/data/repository/restaurant/RestaurantRepositoryImpl.kt @@ -2,7 +2,7 @@ package com.everymeal.data.repository.restaurant import androidx.paging.PagingData import com.everymeal.data.datasource.restaurant.RestaurantDataSource -import com.everymeal.domain.model.restaurant.RestaurantDataEntity +import com.everymeal.domain.model.restaurant.Restaurant import com.everymeal.domain.repository.restaurant.RestaurantRepository import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map @@ -18,10 +18,10 @@ class RestaurantRepositoryImpl @Inject constructor( order: String, group: String?, grade: String? - ) : Flow> { + ) : Flow> { return restaurantDataSource.getUnivRestaurant(campusIdx, order, group, grade) .map { pagingData -> pagingData.map { it.toEntity() } } } -} \ No newline at end of file +} diff --git a/data/src/main/java/com/everymeal/data/repository/search/DefaultSearchRepository.kt b/data/src/main/java/com/everymeal/data/repository/search/DefaultSearchRepository.kt new file mode 100644 index 00000000..069ed460 --- /dev/null +++ b/data/src/main/java/com/everymeal/data/repository/search/DefaultSearchRepository.kt @@ -0,0 +1,17 @@ +package com.everymeal.data.repository.search + +import com.everymeal.data.model.restaruant.toRestaurants +import com.everymeal.data.service.search.SearchService +import com.everymeal.domain.model.restaurant.Restaurant +import com.everymeal.domain.repository.search.SearchRepository +import javax.inject.Inject + +class DefaultSearchRepository @Inject constructor( + private val searchService: SearchService, +) : SearchRepository { + override suspend fun search(keyword: String): Result> { + return runCatching { + searchService.search(keyword).toRestaurants() + } + } +} diff --git a/data/src/main/java/com/everymeal/data/service/search/SearchService.kt b/data/src/main/java/com/everymeal/data/service/search/SearchService.kt new file mode 100644 index 00000000..ef02afa8 --- /dev/null +++ b/data/src/main/java/com/everymeal/data/service/search/SearchService.kt @@ -0,0 +1,13 @@ +package com.everymeal.data.service.search + +import com.everymeal.data.model.restaruant.SearchRestaurantResponse +import retrofit2.http.GET +import retrofit2.http.Path + +interface SearchService { + // TODO 임시 캠퍼스 ID + @GET("/api/v1/stores/{0}/{keyword}") + suspend fun search( + @Path("keyword") keyword: String, + ): SearchRestaurantResponse +} diff --git a/domain/src/main/java/com/everymeal/domain/model/restaurant/RestaurantDataEntity.kt b/domain/src/main/java/com/everymeal/domain/model/restaurant/Restaurant.kt similarity index 91% rename from domain/src/main/java/com/everymeal/domain/model/restaurant/RestaurantDataEntity.kt rename to domain/src/main/java/com/everymeal/domain/model/restaurant/Restaurant.kt index 00353e5c..481318a5 100644 --- a/domain/src/main/java/com/everymeal/domain/model/restaurant/RestaurantDataEntity.kt +++ b/domain/src/main/java/com/everymeal/domain/model/restaurant/Restaurant.kt @@ -1,6 +1,6 @@ package com.everymeal.domain.model.restaurant -data class RestaurantDataEntity( +data class Restaurant( val idx: Int, val name: String, val address: String, diff --git a/domain/src/main/java/com/everymeal/domain/repository/restaurant/RestaurantRepository.kt b/domain/src/main/java/com/everymeal/domain/repository/restaurant/RestaurantRepository.kt index 49b359b2..bb315885 100644 --- a/domain/src/main/java/com/everymeal/domain/repository/restaurant/RestaurantRepository.kt +++ b/domain/src/main/java/com/everymeal/domain/repository/restaurant/RestaurantRepository.kt @@ -1,7 +1,7 @@ package com.everymeal.domain.repository.restaurant import androidx.paging.PagingData -import com.everymeal.domain.model.restaurant.RestaurantDataEntity +import com.everymeal.domain.model.restaurant.Restaurant import kotlinx.coroutines.flow.Flow interface RestaurantRepository { @@ -11,5 +11,5 @@ interface RestaurantRepository { order: String, group: String? = null, grade: String? = null, - ): Flow> + ): Flow> } diff --git a/domain/src/main/java/com/everymeal/domain/repository/search/SearchRepository.kt b/domain/src/main/java/com/everymeal/domain/repository/search/SearchRepository.kt new file mode 100644 index 00000000..cb101ef0 --- /dev/null +++ b/domain/src/main/java/com/everymeal/domain/repository/search/SearchRepository.kt @@ -0,0 +1,7 @@ +package com.everymeal.domain.repository.search + +import com.everymeal.domain.model.restaurant.Restaurant + +interface SearchRepository { + suspend fun search(keyword: String): Result> +} diff --git a/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetUnivRestaurantUseCase.kt b/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetUnivRestaurantUseCase.kt index 4257fb08..00fb3b1b 100644 --- a/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetUnivRestaurantUseCase.kt +++ b/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetUnivRestaurantUseCase.kt @@ -1,7 +1,7 @@ package com.everymeal.domain.usecase.restaurant import androidx.paging.PagingData -import com.everymeal.domain.model.restaurant.RestaurantDataEntity +import com.everymeal.domain.model.restaurant.Restaurant import com.everymeal.domain.repository.restaurant.RestaurantRepository import kotlinx.coroutines.flow.Flow import javax.inject.Inject @@ -14,7 +14,7 @@ class GetUnivRestaurantUseCase @Inject constructor( order: String, group: String?, grade: String? - ) : Flow> { + ) : Flow> { return restaurantRepository.getUnivRestaurant(campusIdx, order, group, grade) } -} \ No newline at end of file +} diff --git a/presentation/src/main/java/com/everymeal/presentation/components/EveryMealRestaurantItem.kt b/presentation/src/main/java/com/everymeal/presentation/components/EveryMealRestaurantItem.kt index 2f6599d1..56c45923 100644 --- a/presentation/src/main/java/com/everymeal/presentation/components/EveryMealRestaurantItem.kt +++ b/presentation/src/main/java/com/everymeal/presentation/components/EveryMealRestaurantItem.kt @@ -30,7 +30,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import coil.compose.AsyncImage -import com.everymeal.domain.model.restaurant.RestaurantDataEntity +import com.everymeal.domain.model.restaurant.Restaurant import com.everymeal.presentation.R import com.everymeal.presentation.ui.theme.EveryMeal_AndroidTheme import com.everymeal.presentation.ui.theme.Gray300 @@ -40,7 +40,7 @@ import com.everymeal.presentation.ui.theme.Gray700 @Composable fun EveryMealRestaurantItem( - restaurant: RestaurantDataEntity, + restaurant: Restaurant, onLoveClick: () -> Unit = {}, onDetailClick: () -> Unit = {}, ) { @@ -68,7 +68,7 @@ fun EveryMealRestaurantItem( @Composable fun RestaurantTitle( modifier: Modifier = Modifier, - restaurant: RestaurantDataEntity, + restaurant: Restaurant, onLoveClick: () -> Unit, ) { Row( @@ -99,7 +99,7 @@ fun RestaurantTitle( @Composable fun RestaurantLoveCount( - restaurant: RestaurantDataEntity, + restaurant: Restaurant, onLoveClick: () -> Unit, ) { Column( @@ -124,7 +124,7 @@ fun RestaurantLoveCount( } @Composable -fun RestaurantRating(restaurant: RestaurantDataEntity) { +fun RestaurantRating(restaurant: Restaurant) { Row( modifier = Modifier .width(100.dp), @@ -153,7 +153,7 @@ fun RestaurantRating(restaurant: RestaurantDataEntity) { } @Composable -fun RestaurantImage(restaurant: RestaurantDataEntity) { +fun RestaurantImage(restaurant: Restaurant) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/bottom/BottomNavigation.kt b/presentation/src/main/java/com/everymeal/presentation/ui/bottom/BottomNavigation.kt index ca0fff57..4b44aa70 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/bottom/BottomNavigation.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/bottom/BottomNavigation.kt @@ -12,23 +12,23 @@ enum class BottomNavigation( HOME( route = EveryMealRoute.HOME.route, icon = R.drawable.icon_store, - title = R.string.bottom_nav_home + title = R.string.bottom_nav_home, ), UNIV_FOOD( route = EveryMealRoute.UNIV_FOOD.route, icon = R.drawable.icon_folk, - title = R.string.bottom_nav_univ_food + title = R.string.bottom_nav_univ_food, ), WHAT_FOOD( route = EveryMealRoute.WHAT_FOOD.route, icon = R.drawable.icon_chat_bubble, - title = R.string.bottom_nav_what_food + title = R.string.bottom_nav_what_food, ), MY_PAGE( route = EveryMealRoute.MY_PAGE.route, icon = R.drawable.icon_user, - title = R.string.bottom_nav_my_tab - ) + title = R.string.bottom_nav_my_tab, + ), } enum class EveryMealRoute(val route: String) { diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListScreen.kt index 3ddb83d1..f514eea4 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListScreen.kt @@ -30,7 +30,7 @@ import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.paging.compose.LazyPagingItems import androidx.paging.compose.collectAsLazyPagingItems -import com.everymeal.domain.model.restaurant.RestaurantDataEntity +import com.everymeal.domain.model.restaurant.Restaurant import com.everymeal.presentation.R import com.everymeal.presentation.components.EveryMealCategoryRatingBottomSheetDialog import com.everymeal.presentation.components.EveryMealDetailReportBottomSheetDialog @@ -51,7 +51,7 @@ fun DetailListScreen( ) { val detailListViewState by detailListViewModel.viewState.collectAsState() - val pagingRestaurantList: LazyPagingItems = + val pagingRestaurantList: LazyPagingItems = detailListViewModel.restaurantItems.collectAsLazyPagingItems() LaunchedEffect(Unit) { diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListViewModel.kt b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListViewModel.kt index efd423fe..cb2d86f1 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListViewModel.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListViewModel.kt @@ -3,7 +3,7 @@ package com.everymeal.presentation.ui.detail import androidx.lifecycle.viewModelScope import androidx.paging.PagingData import androidx.paging.cachedIn -import com.everymeal.domain.model.restaurant.RestaurantDataEntity +import com.everymeal.domain.model.restaurant.Restaurant import com.everymeal.domain.usecase.local.GetUniversityIndexUseCase import com.everymeal.domain.usecase.restaurant.GetUnivRestaurantUseCase import com.everymeal.presentation.base.BaseViewModel @@ -25,8 +25,8 @@ class DetailListViewModel @Inject constructor( ): BaseViewModel( DetailState() ) { - private val _restaurantItems : MutableStateFlow> = MutableStateFlow(value = PagingData.empty()) - val restaurantItems : StateFlow> = _restaurantItems.asStateFlow() + private val _restaurantItems : MutableStateFlow> = MutableStateFlow(value = PagingData.empty()) + val restaurantItems : StateFlow> = _restaurantItems.asStateFlow() override fun handleEvents(event: DetailEvent) { when (event) { @@ -127,4 +127,4 @@ class DetailListViewModel @Inject constructor( ) } } -} \ No newline at end of file +} diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeScreen.kt index 4c188df3..011d7b70 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeScreen.kt @@ -39,7 +39,7 @@ 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 com.everymeal.domain.model.restaurant.RestaurantDataEntity +import com.everymeal.domain.model.restaurant.Restaurant import com.everymeal.presentation.R import com.everymeal.presentation.components.EveryMealLineButton import com.everymeal.presentation.components.EveryMealMainBottomSheetDialog @@ -61,7 +61,7 @@ fun HomeScreen( onReviewBottomSheetClick: () -> Unit, ) { val items = listOf( - RestaurantDataEntity( + Restaurant( idx = 386, name = "히포 브런치하우스", address = "서울 마포구 연남동 487-34", @@ -79,7 +79,7 @@ fun HomeScreen( ), isLiked = false, ), - RestaurantDataEntity( + Restaurant( idx = 386, name = "히포 브런치하우스", address = "서울 마포구 연남동 487-34", diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchContract.kt b/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchContract.kt index 66acfaef..52962d89 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchContract.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchContract.kt @@ -1,6 +1,6 @@ package com.everymeal.presentation.ui.search -import com.everymeal.domain.model.restaurant.RestaurantDataEntity +import com.everymeal.domain.model.restaurant.Restaurant import com.everymeal.presentation.base.ViewEvent import com.everymeal.presentation.base.ViewSideEffect import com.everymeal.presentation.base.ViewState @@ -13,7 +13,7 @@ data class SearchState( val searchQuery: String = "", val searchIsShowHistory: Boolean = true, val searchHistoryItems: List = listOf(), - val searchResultList: List = listOf(), + val searchResultList: List = listOf(), ) : ViewState sealed class SearchEvent : ViewEvent { @@ -25,9 +25,7 @@ sealed class SearchEvent : ViewEvent { val historyItems: List, ) : SearchEvent() - data class SearchResultLoaded( - val searchResultList: List, - ) : SearchEvent() + object SearchRestaurant : SearchEvent() } sealed class SearchEffect : ViewSideEffect diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchScreen.kt index c0ad0051..9afdb768 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchScreen.kt @@ -29,7 +29,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavController -import com.everymeal.domain.model.restaurant.RestaurantDataEntity +import com.everymeal.domain.model.restaurant.Restaurant import com.everymeal.presentation.R import com.everymeal.presentation.components.EveryMealRestaurantItem import com.everymeal.presentation.ui.search.history.SearchHistoryList @@ -46,6 +46,9 @@ fun SearchScreen( Scaffold( topBar = { SearchTopBar( + modifier = Modifier + .fillMaxWidth() + .padding(top = 14.dp, end = 20.dp), onBackClick = { }, searchQuery = viewState.value.searchQuery, changeQuery = { viewModel.setEvent(SearchEvent.SearchQueryChanged(it)) }, @@ -80,7 +83,7 @@ fun SearchScreen( @Composable fun SearchDetail( modifier: Modifier = Modifier, - searchResultList: List, + searchResultList: List, ) { LazyColumn(modifier = modifier) { itemsIndexed(searchResultList) { index, restaurant -> diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchViewModel.kt b/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchViewModel.kt index 7b674481..415ccd4a 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchViewModel.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchViewModel.kt @@ -1,13 +1,16 @@ package com.everymeal.presentation.ui.search import androidx.lifecycle.viewModelScope +import com.everymeal.domain.repository.search.SearchRepository import com.everymeal.presentation.base.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel -class SearchViewModel @Inject constructor() : +class SearchViewModel @Inject constructor( + private val searchRepository: SearchRepository, +) : BaseViewModel(SearchState()) { init { updateState { @@ -31,22 +34,27 @@ class SearchViewModel @Inject constructor() : copy(searchHistoryItems = event.historyItems) } } - is SearchEvent.SearchResultLoaded -> { - updateState { - copy( - searchResultList = event.searchResultList, - searchIsShowHistory = false, - ) - } + is SearchEvent.SearchRestaurant -> { + search() } } } private fun search() { viewModelScope.launch { -// val result = repository.getUnivRestaurant(1, "test") -// setEvent(SearchEvent.SearchResultLoaded(result)) + val keyword = viewState.value.searchQuery + if (keyword.isEmpty()) { + return@launch + } + searchRepository.search(keyword).onSuccess { result -> + updateState { + copy( + searchResultList = result, + searchIsShowHistory = false, + ) + } + } } } } diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/search/topbar/SearchTopBar.kt b/presentation/src/main/java/com/everymeal/presentation/ui/search/topbar/SearchTopBar.kt index 2723584e..c1c5ceff 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/search/topbar/SearchTopBar.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/search/topbar/SearchTopBar.kt @@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -24,19 +25,16 @@ fun SearchTopBar( onBackClick: () -> Unit, ) { Row( - modifier = modifier - .fillMaxWidth() - .padding(top = 14.dp), + modifier = modifier, + verticalAlignment = Alignment.CenterVertically, ) { Image( - painter = painterResource(id = R.drawable.ic_launcher_foreground), + painter = painterResource(id = R.drawable.icon_arrow_back_mono), contentDescription = null, - modifier = modifier + modifier = Modifier .size(48.dp) .padding(12.dp) - .clickable { - onBackClick() - }, + .clickable(onClick = onBackClick), ) SearchBar( searchQuery = searchQuery, From 2f17afabfee41ab7f29230f13fcfb28dc2c316fc Mon Sep 17 00:00:00 2001 From: KwakEuiJin Date: Sun, 4 Feb 2024 14:33:56 +0900 Subject: [PATCH 4/9] =?UTF-8?q?[feat/review=5Fapi]:=20Hilt=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../everymeal_android/di/NetworkModule.kt | 23 ++++++++++++------- .../everymeal_android/di/RepositoryModule.kt | 8 +++++++ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/everymeal/everymeal_android/di/NetworkModule.kt b/app/src/main/java/com/everymeal/everymeal_android/di/NetworkModule.kt index 70c16498..20b48a78 100644 --- a/app/src/main/java/com/everymeal/everymeal_android/di/NetworkModule.kt +++ b/app/src/main/java/com/everymeal/everymeal_android/di/NetworkModule.kt @@ -4,6 +4,7 @@ import com.everymeal.data.service.auth.AuthApi import com.everymeal.data.service.onboarding.OnboardingApi import com.everymeal.data.service.restaurant.RestaurantApi import com.everymeal.data.service.review.StoreReviewApi +import com.everymeal.data.service.search.SearchService import com.everymeal.everymeal_android.BuildConfig import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory import dagger.Module @@ -31,20 +32,20 @@ object NetworkModule { fun provideClient(): OkHttpClient { val interceptor = HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY) return OkHttpClient.Builder() - .addInterceptor(interceptor) - .connectTimeout(100, TimeUnit.SECONDS) - .readTimeout(100, TimeUnit.SECONDS) - .build() + .addInterceptor(interceptor) + .connectTimeout(100, TimeUnit.SECONDS) + .readTimeout(100, TimeUnit.SECONDS) + .build() } @Provides @Singleton fun provideRetrofit(client: OkHttpClient): Retrofit { return Retrofit.Builder() - .baseUrl(BASE_URL) - .addConverterFactory(json.asConverterFactory(contentType)) - .client(client) - .build() + .baseUrl(BASE_URL) + .addConverterFactory(json.asConverterFactory(contentType)) + .client(client) + .build() } @Provides @@ -70,4 +71,10 @@ object NetworkModule { fun provideReviewApi(retrofit: Retrofit): StoreReviewApi { return retrofit.create(StoreReviewApi::class.java) } + + @Provides + @Singleton + fun provideSearchApi(retrofit: Retrofit): SearchService { + return retrofit.create(SearchService::class.java) + } } diff --git a/app/src/main/java/com/everymeal/everymeal_android/di/RepositoryModule.kt b/app/src/main/java/com/everymeal/everymeal_android/di/RepositoryModule.kt index d557bf53..148bdf85 100644 --- a/app/src/main/java/com/everymeal/everymeal_android/di/RepositoryModule.kt +++ b/app/src/main/java/com/everymeal/everymeal_android/di/RepositoryModule.kt @@ -15,11 +15,13 @@ import com.everymeal.data.repository.local.LocalRepositoryImpl import com.everymeal.data.repository.onboarding.OnboardingRepositoryImpl import com.everymeal.data.repository.restaurant.RestaurantRepositoryImpl import com.everymeal.data.repository.review.DefaultReviewRepository +import com.everymeal.data.repository.search.DefaultSearchRepository import com.everymeal.domain.repository.auth.AuthRepository import com.everymeal.domain.repository.local.LocalRepository import com.everymeal.domain.repository.onboarding.OnboardingRepository import com.everymeal.domain.repository.restaurant.RestaurantRepository import com.everymeal.domain.repository.review.ReviewRepository +import com.everymeal.domain.repository.search.SearchRepository import dagger.Binds import dagger.Module import dagger.hilt.InstallIn @@ -89,4 +91,10 @@ abstract class RepositoryModule { abstract fun bindReviewRepository( defaultReviewRepository: DefaultReviewRepository, ): ReviewRepository + + @Singleton + @Binds + abstract fun bindSearchRepository( + defaultSearchRepository: DefaultSearchRepository, + ): SearchRepository } From ade5cc21a98421fa0ae43543a5d6f5250642fa35 Mon Sep 17 00:00:00 2001 From: KwakEuiJin Date: Sun, 4 Feb 2024 14:57:25 +0900 Subject: [PATCH 5/9] =?UTF-8?q?[feat/review=5Fapi]:=20Hilt=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EB=94=94=EC=9E=90?= =?UTF-8?q?=EC=9D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/ui/home/HomeScreen.kt | 1 + .../presentation/ui/review/ReviewScreen.kt | 1 - .../ui/review/search/ReviewSearchScreen.kt | 29 ++++++------------- .../ui/search/history/SearchHistoryList.kt | 10 +++++-- .../ui/search/topbar/SearchTopBar.kt | 5 +--- .../res/drawable/img_review_searchbar.xml | 20 +++++++++++++ 6 files changed, 39 insertions(+), 27 deletions(-) create mode 100644 presentation/src/main/res/drawable/img_review_searchbar.xml diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeScreen.kt index 011d7b70..b53793cd 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeScreen.kt @@ -107,6 +107,7 @@ fun HomeScreen( content = stringResource(id = R.string.univ_admin_review_content), onClick = { onReviewBottomSheetClick() + homeViewModel.setEvent(HomeContract.HomeEvent.BottomSheetStateChange(false)) }, onDismiss = { homeViewModel.setEvent(HomeContract.HomeEvent.BottomSheetStateChange(false)) diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreen.kt index 4767bac6..8e5dcee4 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/review/ReviewScreen.kt @@ -43,7 +43,6 @@ import androidx.hilt.navigation.compose.hiltViewModel import com.everymeal.presentation.R import com.everymeal.presentation.components.EveryMealDialog import com.everymeal.presentation.ui.review.write.ReviewWriteScreen -import com.everymeal.presentation.ui.search.topbar.SearchBar import com.everymeal.presentation.ui.theme.Gray600 import com.everymeal.presentation.ui.theme.Grey2 import com.everymeal.presentation.ui.theme.Grey9 diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/review/search/ReviewSearchScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/review/search/ReviewSearchScreen.kt index 62b8e0b3..29065486 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/review/search/ReviewSearchScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/review/search/ReviewSearchScreen.kt @@ -1,5 +1,6 @@ package com.everymeal.presentation.ui.review.search +import androidx.compose.foundation.Image import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -9,13 +10,13 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.navigation.NavController import com.everymeal.presentation.R import com.everymeal.presentation.ui.bottom.EveryMealRoute import com.everymeal.presentation.ui.review.ReviewTopBar -import com.everymeal.presentation.ui.search.topbar.SearchBar import com.everymeal.presentation.ui.theme.Typography @Composable @@ -36,13 +37,15 @@ fun ReviewSearchScreen( Box(modifier = Modifier.padding(innerPadding)) { Column { ReviewGuideHeader() - ReviewSearchBar( + Image( modifier = Modifier .padding(top = 28.dp) - .padding(horizontal = 20.dp), - searchBarClicked = { - navController.navigate(EveryMealRoute.SEARCH.route) - }, + .padding(horizontal = 20.dp) + .clickable { + navController.navigate(EveryMealRoute.SEARCH.route) + }, + painter = painterResource(id = R.drawable.img_review_searchbar), + contentDescription = null ) } } @@ -60,17 +63,3 @@ fun ReviewGuideHeader( style = Typography.titleLarge, ) } - -@Composable -fun ReviewSearchBar( - modifier: Modifier = Modifier, - searchBarClicked: () -> Unit, -) { - SearchBar( - modifier = modifier.clickable { - searchBarClicked() - }, - searchQuery = "", - changeQuery = {}, - ) -} diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/search/history/SearchHistoryList.kt b/presentation/src/main/java/com/everymeal/presentation/ui/search/history/SearchHistoryList.kt index fa691ca5..0c7e60aa 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/search/history/SearchHistoryList.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/search/history/SearchHistoryList.kt @@ -22,6 +22,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.everymeal.presentation.R import com.everymeal.presentation.ui.theme.Gray500 +import com.everymeal.presentation.ui.theme.Gray900 @Composable fun SearchHistoryList( @@ -51,12 +52,17 @@ fun SearchHistoryList( Row( modifier = Modifier .fillMaxWidth() - .padding(vertical = 16.dp), + .padding(vertical = 16.dp) + .clickable { onHistoryItemClicked(item) }, horizontalArrangement = Arrangement.SpaceBetween, ) { Text( text = item, - modifier = Modifier.clickable { onHistoryItemClicked(item) }, + style = TextStyle( + fontSize = 16.sp, + fontWeight = FontWeight(400), + color = Gray900 + ) ) Icon( imageVector = Icons.Default.Close, diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/search/topbar/SearchTopBar.kt b/presentation/src/main/java/com/everymeal/presentation/ui/search/topbar/SearchTopBar.kt index c1c5ceff..d8683108 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/search/topbar/SearchTopBar.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/search/topbar/SearchTopBar.kt @@ -5,7 +5,6 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable @@ -51,9 +50,7 @@ fun SearchBar( ) { Box(modifier = modifier) { EveryMealTextField( - modifier = Modifier - .fillMaxWidth() - .heightIn(min = 56.dp), + modifier = Modifier.fillMaxWidth(), value = searchQuery, onValueChange = { changeQuery(it) diff --git a/presentation/src/main/res/drawable/img_review_searchbar.xml b/presentation/src/main/res/drawable/img_review_searchbar.xml new file mode 100644 index 00000000..bcf39c18 --- /dev/null +++ b/presentation/src/main/res/drawable/img_review_searchbar.xml @@ -0,0 +1,20 @@ + + + + + + From ae8fd9ce1a1640285cb6d4c71b4275300d74ee08 Mon Sep 17 00:00:00 2001 From: KwakEuiJin Date: Sun, 4 Feb 2024 15:09:05 +0900 Subject: [PATCH 6/9] =?UTF-8?q?[feat/review=5Fapi]:=20EveryMealTextField?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/EveryMealTextFiled.kt | 16 +++++++++++++++- .../presentation/ui/search/SearchScreen.kt | 1 + .../ui/search/topbar/SearchTopBar.kt | 9 +++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/presentation/src/main/java/com/everymeal/presentation/components/EveryMealTextFiled.kt b/presentation/src/main/java/com/everymeal/presentation/components/EveryMealTextFiled.kt index 20ffe883..34b19a2d 100644 --- a/presentation/src/main/java/com/everymeal/presentation/components/EveryMealTextFiled.kt +++ b/presentation/src/main/java/com/everymeal/presentation/components/EveryMealTextFiled.kt @@ -1,6 +1,8 @@ package com.everymeal.presentation.components import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.Text import androidx.compose.material3.TextField import androidx.compose.material3.TextFieldDefaults @@ -9,6 +11,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.everymeal.presentation.ui.theme.Gray300 @@ -23,6 +26,8 @@ fun EveryMealTextField( isError: Boolean = false, supportingText: (@Composable () -> Unit)? = null, leadingIcon: (@Composable () -> Unit)? = null, + maxLines: Int = Int.MAX_VALUE, + onEnterPressed: (() -> Unit)? = null, // 'onSearch' 대신 'onEnterPressed' 사용 otherCustomization: (@Composable () -> Unit)? = null ) { TextField( @@ -42,6 +47,15 @@ fun EveryMealTextField( ) ) }, + maxLines = maxLines, + keyboardOptions = KeyboardOptions.Default.copy( + imeAction = if (onEnterPressed != null) ImeAction.Search else ImeAction.Default + ), + keyboardActions = KeyboardActions( + onSearch = { + onEnterPressed?.invoke() + } + ), shape = RoundedCornerShape(12.dp), colors = TextFieldDefaults.colors( focusedContainerColor = Gray300, @@ -49,7 +63,7 @@ fun EveryMealTextField( focusedIndicatorColor = Color.Transparent, unfocusedIndicatorColor = Color.Transparent, disabledIndicatorColor = Color.Transparent - ), + ) ) otherCustomization?.invoke() } diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchScreen.kt index 9afdb768..e9367581 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchScreen.kt @@ -52,6 +52,7 @@ fun SearchScreen( onBackClick = { }, searchQuery = viewState.value.searchQuery, changeQuery = { viewModel.setEvent(SearchEvent.SearchQueryChanged(it)) }, + onSearchAction = { viewModel.setEvent(SearchEvent.SearchRestaurant) }, ) }, containerColor = Color.White, diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/search/topbar/SearchTopBar.kt b/presentation/src/main/java/com/everymeal/presentation/ui/search/topbar/SearchTopBar.kt index d8683108..b0af7585 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/search/topbar/SearchTopBar.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/search/topbar/SearchTopBar.kt @@ -20,8 +20,9 @@ import com.everymeal.presentation.components.EveryMealTextField fun SearchTopBar( modifier: Modifier = Modifier, searchQuery: String, - changeQuery: (String) -> Unit, - onBackClick: () -> Unit, + changeQuery: (String) -> Unit = {}, + onBackClick: () -> Unit = {}, + onSearchAction: () -> Unit = {} ) { Row( modifier = modifier, @@ -38,6 +39,7 @@ fun SearchTopBar( SearchBar( searchQuery = searchQuery, changeQuery = changeQuery, + onSearchAction = onSearchAction ) } } @@ -47,6 +49,7 @@ fun SearchBar( modifier: Modifier = Modifier, searchQuery: String, changeQuery: (String) -> Unit, + onSearchAction: () -> Unit = {}, ) { Box(modifier = modifier) { EveryMealTextField( @@ -62,6 +65,8 @@ fun SearchBar( contentDescription = null, ) }, + maxLines = 1, + onEnterPressed = onSearchAction, ) } } From b2c1ce78da35bfeaed28a665b508373e59c24577 Mon Sep 17 00:00:00 2001 From: KwakEuiJin Date: Sun, 4 Feb 2024 15:20:45 +0900 Subject: [PATCH 7/9] =?UTF-8?q?[feat/review=5Fapi]:=20Merge=20Error=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../restaurant/RestaurantRepositoryImpl.kt | 8 +-- .../restaurant/GetDetailRestaurantUseCase.kt | 6 +- .../com/everymeal/domain/ExampleUnitTest.kt | 16 ----- .../ui/restaurant/DetailRestaurantContract.kt | 7 +- .../ui/restaurant/DetailRestaurantScreen.kt | 66 +++++++++++++------ .../restaurant/DetailRestaurantViewModel.kt | 7 +- 6 files changed, 58 insertions(+), 52 deletions(-) delete mode 100644 domain/src/test/java/com/everymeal/domain/ExampleUnitTest.kt diff --git a/data/src/main/java/com/everymeal/data/repository/restaurant/RestaurantRepositoryImpl.kt b/data/src/main/java/com/everymeal/data/repository/restaurant/RestaurantRepositoryImpl.kt index 669d1a9f..f9ce85b1 100644 --- a/data/src/main/java/com/everymeal/data/repository/restaurant/RestaurantRepositoryImpl.kt +++ b/data/src/main/java/com/everymeal/data/repository/restaurant/RestaurantRepositoryImpl.kt @@ -1,13 +1,13 @@ package com.everymeal.data.repository.restaurant import androidx.paging.PagingData +import androidx.paging.map import com.everymeal.data.datasource.restaurant.RestaurantDataSource +import com.everymeal.data.model.restaruant.toEntity import com.everymeal.domain.model.restaurant.Restaurant import com.everymeal.domain.repository.restaurant.RestaurantRepository import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map -import androidx.paging.map -import com.everymeal.data.model.restaruant.toEntity import javax.inject.Inject class RestaurantRepositoryImpl @Inject constructor( @@ -18,14 +18,14 @@ class RestaurantRepositoryImpl @Inject constructor( order: String, group: String?, grade: String? - ) : Flow> { + ): Flow> { return restaurantDataSource.getUnivRestaurant(campusIdx, order, group, grade) .map { pagingData -> pagingData.map { it.toEntity() } } } - override suspend fun getRestaurantDetail(index: Int): Result { + override suspend fun getRestaurantDetail(index: Int): Result { return restaurantDataSource.getRestaurantDetail(index).map { it.toEntity() } } } diff --git a/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetDetailRestaurantUseCase.kt b/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetDetailRestaurantUseCase.kt index a6536bde..cac40122 100644 --- a/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetDetailRestaurantUseCase.kt +++ b/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetDetailRestaurantUseCase.kt @@ -1,6 +1,6 @@ package com.everymeal.domain.usecase.restaurant -import com.everymeal.domain.model.restaurant.RestaurantDataEntity +import com.everymeal.domain.model.restaurant.Restaurant import com.everymeal.domain.repository.restaurant.RestaurantRepository import javax.inject.Inject @@ -9,7 +9,7 @@ class GetDetailRestaurantUseCase @Inject constructor( ) { suspend operator fun invoke( restaurantIdx: Int, - ) : Result { + ): Result { return restaurantRepository.getRestaurantDetail(restaurantIdx) } -} \ No newline at end of file +} diff --git a/domain/src/test/java/com/everymeal/domain/ExampleUnitTest.kt b/domain/src/test/java/com/everymeal/domain/ExampleUnitTest.kt deleted file mode 100644 index 9448d257..00000000 --- a/domain/src/test/java/com/everymeal/domain/ExampleUnitTest.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.everymeal.domain - -import org.junit.Assert.assertEquals -import org.junit.Test - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -} diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantContract.kt b/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantContract.kt index 5b13177f..9fbd3baf 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantContract.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantContract.kt @@ -1,11 +1,10 @@ package com.everymeal.presentation.ui.restaurant -import com.everymeal.domain.model.restaurant.RestaurantDataEntity +import com.everymeal.domain.model.restaurant.Restaurant import com.everymeal.presentation.base.LoadState import com.everymeal.presentation.base.ViewEvent import com.everymeal.presentation.base.ViewSideEffect import com.everymeal.presentation.base.ViewState -import com.everymeal.presentation.ui.signup.UnivSelectContract data class DetailRestaurantState( @@ -13,7 +12,7 @@ data class DetailRestaurantState( val selectedTabIndex: Int = 0, val isFabClicked: Boolean = false, val getDetailRestaurantState: LoadState = LoadState.LOADING, - val restaurantInfo: RestaurantDataEntity = RestaurantDataEntity( + val restaurantInfo: Restaurant = Restaurant( idx = 0, name = "", address = "", @@ -38,4 +37,4 @@ sealed class DetailRestaurantEvent : ViewEvent { sealed class DetailRestaurantEffect : ViewSideEffect { -} \ No newline at end of file +} diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantScreen.kt index 1d012fb7..c7414f62 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantScreen.kt @@ -49,13 +49,12 @@ 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 com.everymeal.domain.model.restaurant.RestaurantDataEntity +import com.everymeal.domain.model.restaurant.Restaurant import com.everymeal.presentation.R import com.everymeal.presentation.base.LoadState import com.everymeal.presentation.components.EveryMealDialog import com.everymeal.presentation.components.EveryMealLoadingDialog import com.everymeal.presentation.ui.save.SaveTopBar -import com.everymeal.presentation.ui.signup.UnivSelectContract import com.everymeal.presentation.ui.theme.EveryMealTypo import com.everymeal.presentation.ui.theme.Gray100 import com.everymeal.presentation.ui.theme.Gray300 @@ -79,13 +78,18 @@ fun DetailRestaurantScreen( val restaurantInfo = viewState.restaurantInfo LaunchedEffect(Unit) { - detailRestaurantViewModel.setEvent(DetailRestaurantEvent.InitDetailRestaurantScreen(restaurantId)) + detailRestaurantViewModel.setEvent( + DetailRestaurantEvent.InitDetailRestaurantScreen( + restaurantId + ) + ) } - when(viewState.getDetailRestaurantState) { + when (viewState.getDetailRestaurantState) { LoadState.LOADING -> { EveryMealLoadingDialog() } + LoadState.SUCCESS -> { Scaffold( topBar = { @@ -109,12 +113,12 @@ fun DetailRestaurantScreen( ) { Image( imageVector = - if(viewState.isFabClicked) + if (viewState.isFabClicked) ImageVector.vectorResource(R.drawable.icon_x_mono) else ImageVector.vectorResource(R.drawable.icon_pencil_mono), contentDescription = "floating", - colorFilter = ColorFilter.tint(if(viewState.isFabClicked) Gray800 else Color.White), + colorFilter = ColorFilter.tint(if (viewState.isFabClicked) Gray800 else Color.White), ) } }, @@ -124,7 +128,7 @@ fun DetailRestaurantScreen( modifier = Modifier.padding(innerPadding), ) { // Todo Test 필요 - if(!restaurantInfo.images.isNullOrEmpty()) { + if (!restaurantInfo.images.isNullOrEmpty()) { item { DetailRestaurantImage() } @@ -153,7 +157,7 @@ fun DetailRestaurantScreen( ) ) }, - contentAlignment=Alignment.BottomEnd + contentAlignment = Alignment.BottomEnd ) { Row( modifier = Modifier @@ -197,8 +201,9 @@ fun DetailRestaurantScreen( } } } + LoadState.ERROR -> { - if(viewState.networkErrorDialog) { + if (viewState.networkErrorDialog) { EveryMealDialog( modifier = Modifier.fillMaxWidth(), title = stringResource(R.string.error_dialog_title), @@ -207,12 +212,28 @@ fun DetailRestaurantScreen( dismissButtonText = stringResource(R.string.cancel), onDismissRequest = { }, onConfirmClick = { - detailRestaurantViewModel.setEvent(DetailRestaurantEvent.NetworkErrorDialogClicked(false)) - detailRestaurantViewModel.setEvent(DetailRestaurantEvent.InitDetailRestaurantScreen(restaurantId)) - detailRestaurantViewModel.setEvent(DetailRestaurantEvent.NetworkErrorDialogClicked(true)) + detailRestaurantViewModel.setEvent( + DetailRestaurantEvent.NetworkErrorDialogClicked( + false + ) + ) + detailRestaurantViewModel.setEvent( + DetailRestaurantEvent.InitDetailRestaurantScreen( + restaurantId + ) + ) + detailRestaurantViewModel.setEvent( + DetailRestaurantEvent.NetworkErrorDialogClicked( + true + ) + ) }, onDisMissClicked = { - detailRestaurantViewModel.setEvent(DetailRestaurantEvent.NetworkErrorDialogClicked(false)) + detailRestaurantViewModel.setEvent( + DetailRestaurantEvent.NetworkErrorDialogClicked( + false + ) + ) onNetWorkErrorCancelClick() } ) @@ -253,7 +274,7 @@ fun DetailRestaurantImage( @Composable fun DetailRestaurantMainInfo( - restaurantInfo : RestaurantDataEntity + restaurantInfo: Restaurant ) { Column( modifier = Modifier @@ -365,8 +386,8 @@ fun DetailRestaurantMainInfo( @OptIn(ExperimentalFoundationApi::class) @Composable fun DetailRestaurantTabLayout( - restaurantInfo : RestaurantDataEntity, - viewModel : DetailRestaurantViewModel + restaurantInfo: Restaurant, + viewModel: DetailRestaurantViewModel ) { val viewState by viewModel.viewState.collectAsState() @@ -397,10 +418,12 @@ fun DetailRestaurantTabLayout( ) { pages.forEachIndexed { index, title -> Tab( - text = { Text( - text = title, - style = EveryMealTypo.labelSmall, - ) }, + text = { + Text( + text = title, + style = EveryMealTypo.labelSmall, + ) + }, selected = viewState.selectedTabIndex == index, onClick = { coroutineScope.launch { @@ -419,6 +442,7 @@ fun DetailRestaurantTabLayout( restaurantInfo = restaurantInfo, modifier = Modifier.padding(horizontal = 20.dp) ) + 1 -> DetailRestaurantTabImage() 2 -> DetailRestaurantReview() } @@ -427,7 +451,7 @@ fun DetailRestaurantTabLayout( @Composable fun DetailRestaurantTabInfo( - restaurantInfo : RestaurantDataEntity, + restaurantInfo: Restaurant, modifier: Modifier = Modifier, ) { Column( diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantViewModel.kt b/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantViewModel.kt index b00753c2..9702c9b9 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantViewModel.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantViewModel.kt @@ -1,12 +1,11 @@ package com.everymeal.presentation.ui.restaurant import androidx.lifecycle.viewModelScope -import com.everymeal.domain.model.restaurant.RestaurantDataEntity +import com.everymeal.domain.model.restaurant.Restaurant import com.everymeal.domain.usecase.restaurant.GetDetailRestaurantUseCase import com.everymeal.presentation.base.BaseViewModel import com.everymeal.presentation.base.LoadState import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.delay import kotlinx.coroutines.launch import javax.inject.Inject @@ -57,7 +56,7 @@ class DetailRestaurantViewModel @Inject constructor( private fun reflectUpdateState( selectedTabIndex: Int = viewState.value.selectedTabIndex, isFabClicked: Boolean = viewState.value.isFabClicked, - restaurantInfo: RestaurantDataEntity = viewState.value.restaurantInfo, + restaurantInfo: Restaurant = viewState.value.restaurantInfo, getDetailRestaurantState: LoadState = viewState.value.getDetailRestaurantState, networkErrorDialog: Boolean = viewState.value.networkErrorDialog ) { @@ -71,4 +70,4 @@ class DetailRestaurantViewModel @Inject constructor( ) } } -} \ No newline at end of file +} From ac87aca159976b20707f88671d851375f0c8b46d Mon Sep 17 00:00:00 2001 From: KwakEuiJin Date: Sun, 4 Feb 2024 16:28:26 +0900 Subject: [PATCH 8/9] =?UTF-8?q?[feat/review=5Fapi]:=20Merge=20Error=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/restaruant/GetUnivRestaurantResponse.kt | 10 +++++----- .../restaurant/RestaurantRepositoryImpl.kt | 14 +++++++------- .../model/restaurant/GetUnivRestaurantEntity.kt | 5 +++++ .../repository/restaurant/RestaurantRepository.kt | 1 - .../everymeal/presentation/ui/home/HomeContract.kt | 5 ++--- .../ui/restaurant/DetailRestaurantScreen.kt | 4 ++-- 6 files changed, 21 insertions(+), 18 deletions(-) create mode 100644 domain/src/main/java/com/everymeal/domain/model/restaurant/GetUnivRestaurantEntity.kt diff --git a/data/src/main/java/com/everymeal/data/model/restaruant/GetUnivRestaurantResponse.kt b/data/src/main/java/com/everymeal/data/model/restaruant/GetUnivRestaurantResponse.kt index 1aa425ba..6f4f8bfe 100644 --- a/data/src/main/java/com/everymeal/data/model/restaruant/GetUnivRestaurantResponse.kt +++ b/data/src/main/java/com/everymeal/data/model/restaruant/GetUnivRestaurantResponse.kt @@ -1,8 +1,7 @@ package com.everymeal.data.model.restaruant -import com.everymeal.domain.model.restaurant.Restaurant import com.everymeal.domain.model.restaurant.GetUnivRestaurantEntity -import com.everymeal.domain.model.restaurant.RestaurantDataEntity +import com.everymeal.domain.model.restaurant.Restaurant import kotlinx.serialization.Serializable @Serializable @@ -52,7 +51,7 @@ data class Sort( val unsorted: Boolean, ) -fun RestaurantResponse.toEntity(): Restaurant { +fun RestaurantResponse.toRestaurant(): Restaurant { return Restaurant( idx = this.idx, name = this.name, @@ -68,8 +67,9 @@ fun RestaurantResponse.toEntity(): Restaurant { ) } -fun GetUnivRestaurantResponse.toEntity(): GetUnivRestaurantEntity { + +fun GetUnivRestaurantResponse.toGetUnivRestaurantEntity(): GetUnivRestaurantEntity { return GetUnivRestaurantEntity( - data = this.content.map { it.toEntity() } + data = this.content.map { it.toRestaurant() } ) } diff --git a/data/src/main/java/com/everymeal/data/repository/restaurant/RestaurantRepositoryImpl.kt b/data/src/main/java/com/everymeal/data/repository/restaurant/RestaurantRepositoryImpl.kt index fc57ed09..6f3986b8 100644 --- a/data/src/main/java/com/everymeal/data/repository/restaurant/RestaurantRepositoryImpl.kt +++ b/data/src/main/java/com/everymeal/data/repository/restaurant/RestaurantRepositoryImpl.kt @@ -3,14 +3,13 @@ package com.everymeal.data.repository.restaurant import androidx.paging.PagingData import androidx.paging.map import com.everymeal.data.datasource.restaurant.RestaurantDataSource -import com.everymeal.data.model.restaruant.toEntity +import com.everymeal.data.model.restaruant.toGetUnivRestaurantEntity +import com.everymeal.data.model.restaruant.toRestaurant +import com.everymeal.domain.model.restaurant.GetUnivRestaurantEntity import com.everymeal.domain.model.restaurant.Restaurant import com.everymeal.domain.repository.restaurant.RestaurantRepository import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map -import androidx.paging.map -import com.everymeal.data.model.restaruant.toEntity -import com.everymeal.domain.model.restaurant.GetUnivRestaurantEntity import javax.inject.Inject class RestaurantRepositoryImpl @Inject constructor( @@ -24,12 +23,12 @@ class RestaurantRepositoryImpl @Inject constructor( ): Flow> { return restaurantDataSource.getUnivRestaurant(campusIdx, order, group, grade) .map { pagingData -> - pagingData.map { it.toEntity() } + pagingData.map { it.toRestaurant() } } } override suspend fun getRestaurantDetail(index: Int): Result { - return restaurantDataSource.getRestaurantDetail(index).map { it.toEntity() } + return restaurantDataSource.getRestaurantDetail(index).map { it.toRestaurant() } } override suspend fun getHomeRestaurant( @@ -38,6 +37,7 @@ class RestaurantRepositoryImpl @Inject constructor( group: String?, grade: String? ): Result { - return restaurantDataSource.getHomeRestaurant(campusIdx, order, group, grade).map { it.toEntity() } + return restaurantDataSource.getHomeRestaurant(campusIdx, order, group, grade) + .map { it.toGetUnivRestaurantEntity() } } } diff --git a/domain/src/main/java/com/everymeal/domain/model/restaurant/GetUnivRestaurantEntity.kt b/domain/src/main/java/com/everymeal/domain/model/restaurant/GetUnivRestaurantEntity.kt new file mode 100644 index 00000000..31799943 --- /dev/null +++ b/domain/src/main/java/com/everymeal/domain/model/restaurant/GetUnivRestaurantEntity.kt @@ -0,0 +1,5 @@ +package com.everymeal.domain.model.restaurant + +data class GetUnivRestaurantEntity( + val data: List +) diff --git a/domain/src/main/java/com/everymeal/domain/repository/restaurant/RestaurantRepository.kt b/domain/src/main/java/com/everymeal/domain/repository/restaurant/RestaurantRepository.kt index 569912c0..6f789b19 100644 --- a/domain/src/main/java/com/everymeal/domain/repository/restaurant/RestaurantRepository.kt +++ b/domain/src/main/java/com/everymeal/domain/repository/restaurant/RestaurantRepository.kt @@ -17,7 +17,6 @@ interface RestaurantRepository { suspend fun getRestaurantDetail( index: Int ): Result - ) : Result suspend fun getHomeRestaurant( campusIdx: Int, diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeContract.kt b/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeContract.kt index 80da6f33..901f1676 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeContract.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeContract.kt @@ -1,7 +1,6 @@ package com.everymeal.presentation.ui.home -import com.everymeal.domain.model.restaurant.GetUnivRestaurantEntity -import com.everymeal.domain.model.restaurant.RestaurantDataEntity +import com.everymeal.domain.model.restaurant.Restaurant import com.everymeal.presentation.base.LoadState import com.everymeal.presentation.base.ViewEvent import com.everymeal.presentation.base.ViewSideEffect @@ -12,7 +11,7 @@ class HomeContract { val uiState: LoadState = LoadState.LOADING, val detailListScreenType: DetailListScreenType = DetailListScreenType.RECOMMEND, val bottomSheetState: Boolean = false, - val restaurantData: List = emptyList() + val restaurantData: List = emptyList() ) : ViewState sealed class HomeEvent : ViewEvent { diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantScreen.kt index bab3ba55..1ec3cba0 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantScreen.kt @@ -252,7 +252,7 @@ fun DetailRestaurantScreen( @OptIn(ExperimentalFoundationApi::class) @Composable fun DetailRestaurantImage( - restaurantInfo : RestaurantDataEntity + restaurantInfo : Restaurant ) { val images = restaurantInfo.images ?: listOf() @@ -538,7 +538,7 @@ fun DetailRestaurantTabInfo( @Composable fun DetailRestaurantTabImage( - restaurantInfo : RestaurantDataEntity + restaurantInfo : Restaurant ) { Column { restaurantInfo.images?.let { images -> From 8569431c7f4cd92e0f744a34a125ba523ad0a48c Mon Sep 17 00:00:00 2001 From: KwakEuiJin Date: Sun, 4 Feb 2024 16:34:47 +0900 Subject: [PATCH 9/9] =?UTF-8?q?[feat/review=5Fapi]:=20Data=20class=20Name?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=20=EB=A1=A4=EB=B0=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/restaruant/GetUnivRestaurantResponse.kt | 6 +++--- .../model/restaruant/SearchRestaurantResponse.kt | 6 +++--- .../restaurant/RestaurantRepositoryImpl.kt | 6 +++--- .../repository/search/DefaultSearchRepository.kt | 4 ++-- .../model/restaurant/GetUnivRestaurantEntity.kt | 2 +- .../{Restaurant.kt => RestaurantDataEntity.kt} | 2 +- .../repository/restaurant/RestaurantRepository.kt | 6 +++--- .../domain/repository/search/SearchRepository.kt | 4 ++-- .../restaurant/GetDetailRestaurantUseCase.kt | 4 ++-- .../usecase/restaurant/GetUnivRestaurantUseCase.kt | 4 ++-- .../components/EveryMealRestaurantItem.kt | 13 ++++++------- .../presentation/ui/detail/DetailListScreen.kt | 5 ++--- .../presentation/ui/detail/DetailListViewModel.kt | 7 +++---- .../everymeal/presentation/ui/home/HomeContract.kt | 4 ++-- .../ui/restaurant/DetailRestaurantContract.kt | 4 ++-- .../ui/restaurant/DetailRestaurantScreen.kt | 14 ++++++-------- .../ui/restaurant/DetailRestaurantViewModel.kt | 4 ++-- .../presentation/ui/search/SearchContract.kt | 4 ++-- .../presentation/ui/search/SearchScreen.kt | 4 ++-- 19 files changed, 49 insertions(+), 54 deletions(-) rename domain/src/main/java/com/everymeal/domain/model/restaurant/{Restaurant.kt => RestaurantDataEntity.kt} (91%) diff --git a/data/src/main/java/com/everymeal/data/model/restaruant/GetUnivRestaurantResponse.kt b/data/src/main/java/com/everymeal/data/model/restaruant/GetUnivRestaurantResponse.kt index 6f4f8bfe..1beecb68 100644 --- a/data/src/main/java/com/everymeal/data/model/restaruant/GetUnivRestaurantResponse.kt +++ b/data/src/main/java/com/everymeal/data/model/restaruant/GetUnivRestaurantResponse.kt @@ -1,7 +1,7 @@ package com.everymeal.data.model.restaruant import com.everymeal.domain.model.restaurant.GetUnivRestaurantEntity -import com.everymeal.domain.model.restaurant.Restaurant +import com.everymeal.domain.model.restaurant.RestaurantDataEntity import kotlinx.serialization.Serializable @Serializable @@ -51,8 +51,8 @@ data class Sort( val unsorted: Boolean, ) -fun RestaurantResponse.toRestaurant(): Restaurant { - return Restaurant( +fun RestaurantResponse.toRestaurant(): RestaurantDataEntity { + return RestaurantDataEntity( idx = this.idx, name = this.name, address = this.address, diff --git a/data/src/main/java/com/everymeal/data/model/restaruant/SearchRestaurantResponse.kt b/data/src/main/java/com/everymeal/data/model/restaruant/SearchRestaurantResponse.kt index 7dbd60a2..0c8fb431 100644 --- a/data/src/main/java/com/everymeal/data/model/restaruant/SearchRestaurantResponse.kt +++ b/data/src/main/java/com/everymeal/data/model/restaruant/SearchRestaurantResponse.kt @@ -1,6 +1,6 @@ package com.everymeal.data.model.restaruant -import com.everymeal.domain.model.restaurant.Restaurant +import com.everymeal.domain.model.restaurant.RestaurantDataEntity import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -103,10 +103,10 @@ data class SearchRestaurantResponse( } -fun SearchRestaurantResponse.toRestaurants(): List { +fun SearchRestaurantResponse.toRestaurants(): List { return this.data?.content?.mapNotNull { content -> content?.let { - Restaurant( + RestaurantDataEntity( idx = it.idx ?: 0, name = it.name.orEmpty(), address = it.address.orEmpty(), diff --git a/data/src/main/java/com/everymeal/data/repository/restaurant/RestaurantRepositoryImpl.kt b/data/src/main/java/com/everymeal/data/repository/restaurant/RestaurantRepositoryImpl.kt index 6f3986b8..87cbc778 100644 --- a/data/src/main/java/com/everymeal/data/repository/restaurant/RestaurantRepositoryImpl.kt +++ b/data/src/main/java/com/everymeal/data/repository/restaurant/RestaurantRepositoryImpl.kt @@ -6,7 +6,7 @@ import com.everymeal.data.datasource.restaurant.RestaurantDataSource import com.everymeal.data.model.restaruant.toGetUnivRestaurantEntity import com.everymeal.data.model.restaruant.toRestaurant import com.everymeal.domain.model.restaurant.GetUnivRestaurantEntity -import com.everymeal.domain.model.restaurant.Restaurant +import com.everymeal.domain.model.restaurant.RestaurantDataEntity import com.everymeal.domain.repository.restaurant.RestaurantRepository import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map @@ -20,14 +20,14 @@ class RestaurantRepositoryImpl @Inject constructor( order: String, group: String?, grade: String? - ): Flow> { + ): Flow> { return restaurantDataSource.getUnivRestaurant(campusIdx, order, group, grade) .map { pagingData -> pagingData.map { it.toRestaurant() } } } - override suspend fun getRestaurantDetail(index: Int): Result { + override suspend fun getRestaurantDetail(index: Int): Result { return restaurantDataSource.getRestaurantDetail(index).map { it.toRestaurant() } } diff --git a/data/src/main/java/com/everymeal/data/repository/search/DefaultSearchRepository.kt b/data/src/main/java/com/everymeal/data/repository/search/DefaultSearchRepository.kt index 069ed460..926818ed 100644 --- a/data/src/main/java/com/everymeal/data/repository/search/DefaultSearchRepository.kt +++ b/data/src/main/java/com/everymeal/data/repository/search/DefaultSearchRepository.kt @@ -2,14 +2,14 @@ package com.everymeal.data.repository.search import com.everymeal.data.model.restaruant.toRestaurants import com.everymeal.data.service.search.SearchService -import com.everymeal.domain.model.restaurant.Restaurant +import com.everymeal.domain.model.restaurant.RestaurantDataEntity import com.everymeal.domain.repository.search.SearchRepository import javax.inject.Inject class DefaultSearchRepository @Inject constructor( private val searchService: SearchService, ) : SearchRepository { - override suspend fun search(keyword: String): Result> { + override suspend fun search(keyword: String): Result> { return runCatching { searchService.search(keyword).toRestaurants() } diff --git a/domain/src/main/java/com/everymeal/domain/model/restaurant/GetUnivRestaurantEntity.kt b/domain/src/main/java/com/everymeal/domain/model/restaurant/GetUnivRestaurantEntity.kt index 31799943..904a020e 100644 --- a/domain/src/main/java/com/everymeal/domain/model/restaurant/GetUnivRestaurantEntity.kt +++ b/domain/src/main/java/com/everymeal/domain/model/restaurant/GetUnivRestaurantEntity.kt @@ -1,5 +1,5 @@ package com.everymeal.domain.model.restaurant data class GetUnivRestaurantEntity( - val data: List + val data: List ) diff --git a/domain/src/main/java/com/everymeal/domain/model/restaurant/Restaurant.kt b/domain/src/main/java/com/everymeal/domain/model/restaurant/RestaurantDataEntity.kt similarity index 91% rename from domain/src/main/java/com/everymeal/domain/model/restaurant/Restaurant.kt rename to domain/src/main/java/com/everymeal/domain/model/restaurant/RestaurantDataEntity.kt index 481318a5..00353e5c 100644 --- a/domain/src/main/java/com/everymeal/domain/model/restaurant/Restaurant.kt +++ b/domain/src/main/java/com/everymeal/domain/model/restaurant/RestaurantDataEntity.kt @@ -1,6 +1,6 @@ package com.everymeal.domain.model.restaurant -data class Restaurant( +data class RestaurantDataEntity( val idx: Int, val name: String, val address: String, diff --git a/domain/src/main/java/com/everymeal/domain/repository/restaurant/RestaurantRepository.kt b/domain/src/main/java/com/everymeal/domain/repository/restaurant/RestaurantRepository.kt index 6f789b19..5d2deec5 100644 --- a/domain/src/main/java/com/everymeal/domain/repository/restaurant/RestaurantRepository.kt +++ b/domain/src/main/java/com/everymeal/domain/repository/restaurant/RestaurantRepository.kt @@ -2,7 +2,7 @@ package com.everymeal.domain.repository.restaurant import androidx.paging.PagingData import com.everymeal.domain.model.restaurant.GetUnivRestaurantEntity -import com.everymeal.domain.model.restaurant.Restaurant +import com.everymeal.domain.model.restaurant.RestaurantDataEntity import kotlinx.coroutines.flow.Flow interface RestaurantRepository { @@ -12,11 +12,11 @@ interface RestaurantRepository { order: String, group: String? = null, grade: String? = null, - ): Flow> + ): Flow> suspend fun getRestaurantDetail( index: Int - ): Result + ): Result suspend fun getHomeRestaurant( campusIdx: Int, diff --git a/domain/src/main/java/com/everymeal/domain/repository/search/SearchRepository.kt b/domain/src/main/java/com/everymeal/domain/repository/search/SearchRepository.kt index cb101ef0..50f79e49 100644 --- a/domain/src/main/java/com/everymeal/domain/repository/search/SearchRepository.kt +++ b/domain/src/main/java/com/everymeal/domain/repository/search/SearchRepository.kt @@ -1,7 +1,7 @@ package com.everymeal.domain.repository.search -import com.everymeal.domain.model.restaurant.Restaurant +import com.everymeal.domain.model.restaurant.RestaurantDataEntity interface SearchRepository { - suspend fun search(keyword: String): Result> + suspend fun search(keyword: String): Result> } diff --git a/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetDetailRestaurantUseCase.kt b/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetDetailRestaurantUseCase.kt index cac40122..e455acd3 100644 --- a/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetDetailRestaurantUseCase.kt +++ b/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetDetailRestaurantUseCase.kt @@ -1,6 +1,6 @@ package com.everymeal.domain.usecase.restaurant -import com.everymeal.domain.model.restaurant.Restaurant +import com.everymeal.domain.model.restaurant.RestaurantDataEntity import com.everymeal.domain.repository.restaurant.RestaurantRepository import javax.inject.Inject @@ -9,7 +9,7 @@ class GetDetailRestaurantUseCase @Inject constructor( ) { suspend operator fun invoke( restaurantIdx: Int, - ): Result { + ): Result { return restaurantRepository.getRestaurantDetail(restaurantIdx) } } diff --git a/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetUnivRestaurantUseCase.kt b/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetUnivRestaurantUseCase.kt index 00fb3b1b..42d99f72 100644 --- a/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetUnivRestaurantUseCase.kt +++ b/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetUnivRestaurantUseCase.kt @@ -1,7 +1,7 @@ package com.everymeal.domain.usecase.restaurant import androidx.paging.PagingData -import com.everymeal.domain.model.restaurant.Restaurant +import com.everymeal.domain.model.restaurant.RestaurantDataEntity import com.everymeal.domain.repository.restaurant.RestaurantRepository import kotlinx.coroutines.flow.Flow import javax.inject.Inject @@ -14,7 +14,7 @@ class GetUnivRestaurantUseCase @Inject constructor( order: String, group: String?, grade: String? - ) : Flow> { + ) : Flow> { return restaurantRepository.getUnivRestaurant(campusIdx, order, group, grade) } } diff --git a/presentation/src/main/java/com/everymeal/presentation/components/EveryMealRestaurantItem.kt b/presentation/src/main/java/com/everymeal/presentation/components/EveryMealRestaurantItem.kt index c78511f5..ed08ed75 100644 --- a/presentation/src/main/java/com/everymeal/presentation/components/EveryMealRestaurantItem.kt +++ b/presentation/src/main/java/com/everymeal/presentation/components/EveryMealRestaurantItem.kt @@ -5,7 +5,6 @@ import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource 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 @@ -31,7 +30,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import coil.compose.AsyncImage -import com.everymeal.domain.model.restaurant.Restaurant +import com.everymeal.domain.model.restaurant.RestaurantDataEntity import com.everymeal.presentation.R import com.everymeal.presentation.ui.theme.EveryMeal_AndroidTheme import com.everymeal.presentation.ui.theme.Gray300 @@ -41,7 +40,7 @@ import com.everymeal.presentation.ui.theme.Gray700 @Composable fun EveryMealRestaurantItem( - restaurant: Restaurant, + restaurant: RestaurantDataEntity, onLoveClick: () -> Unit = {}, onDetailClick: (Int) -> Unit = {}, ) { @@ -69,7 +68,7 @@ fun EveryMealRestaurantItem( @Composable fun RestaurantTitle( modifier: Modifier = Modifier, - restaurant: Restaurant, + restaurant: RestaurantDataEntity, onLoveClick: () -> Unit, ) { Row( @@ -101,7 +100,7 @@ fun RestaurantTitle( @Composable fun RestaurantLoveCount( - restaurant: Restaurant, + restaurant: RestaurantDataEntity, onLoveClick: () -> Unit, ) { Column( @@ -128,7 +127,7 @@ fun RestaurantLoveCount( } @Composable -fun RestaurantRating(restaurant: Restaurant) { +fun RestaurantRating(restaurant: RestaurantDataEntity) { Row( modifier = Modifier .width(100.dp), @@ -157,7 +156,7 @@ fun RestaurantRating(restaurant: Restaurant) { } @Composable -fun RestaurantImage(restaurant: Restaurant) { +fun RestaurantImage(restaurant: RestaurantDataEntity) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(6.dp) diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListScreen.kt index 5a9ac53a..53776f89 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListScreen.kt @@ -30,7 +30,7 @@ import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.paging.compose.LazyPagingItems import androidx.paging.compose.collectAsLazyPagingItems -import com.everymeal.domain.model.restaurant.Restaurant +import com.everymeal.domain.model.restaurant.RestaurantDataEntity import com.everymeal.presentation.R import com.everymeal.presentation.components.EveryMealCategoryRatingBottomSheetDialog import com.everymeal.presentation.components.EveryMealDetailReportBottomSheetDialog @@ -38,7 +38,6 @@ import com.everymeal.presentation.components.EveryMealReportBottomSheetDialog import com.everymeal.presentation.components.EveryMealRestaurantItem import com.everymeal.presentation.components.EveryMealSortCategoryBottomSheetDialog import com.everymeal.presentation.ui.save.SaveTopBar -import com.everymeal.presentation.ui.signup.UnivSelectContract import com.everymeal.presentation.ui.theme.Grey2 import com.everymeal.presentation.ui.theme.Grey7 import com.everymeal.presentation.ui.theme.Main100 @@ -53,7 +52,7 @@ fun DetailListScreen( ) { val detailListViewState by detailListViewModel.viewState.collectAsState() - val pagingRestaurantList: LazyPagingItems = + val pagingRestaurantList: LazyPagingItems = detailListViewModel.restaurantItems.collectAsLazyPagingItems() LaunchedEffect(Unit) { diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListViewModel.kt b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListViewModel.kt index 2e4b3783..8bf0e46f 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListViewModel.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListViewModel.kt @@ -3,14 +3,13 @@ package com.everymeal.presentation.ui.detail import androidx.lifecycle.viewModelScope import androidx.paging.PagingData import androidx.paging.cachedIn -import com.everymeal.domain.model.restaurant.Restaurant +import com.everymeal.domain.model.restaurant.RestaurantDataEntity import com.everymeal.domain.usecase.local.GetUniversityIndexUseCase import com.everymeal.domain.usecase.restaurant.GetUnivRestaurantUseCase import com.everymeal.presentation.base.BaseViewModel import com.everymeal.presentation.ui.detail.DetailContract.DetailEvent import com.everymeal.presentation.ui.detail.DetailContract.DetailState import com.everymeal.presentation.ui.detail.DetailContract.DetailEffect -import com.everymeal.presentation.ui.signup.UnivSelectContract import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -26,8 +25,8 @@ class DetailListViewModel @Inject constructor( ): BaseViewModel( DetailState() ) { - private val _restaurantItems : MutableStateFlow> = MutableStateFlow(value = PagingData.empty()) - val restaurantItems : StateFlow> = _restaurantItems.asStateFlow() + private val _restaurantItems : MutableStateFlow> = MutableStateFlow(value = PagingData.empty()) + val restaurantItems : StateFlow> = _restaurantItems.asStateFlow() override fun handleEvents(event: DetailEvent) { when (event) { diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeContract.kt b/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeContract.kt index 901f1676..43a90fa0 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeContract.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/home/HomeContract.kt @@ -1,6 +1,6 @@ package com.everymeal.presentation.ui.home -import com.everymeal.domain.model.restaurant.Restaurant +import com.everymeal.domain.model.restaurant.RestaurantDataEntity import com.everymeal.presentation.base.LoadState import com.everymeal.presentation.base.ViewEvent import com.everymeal.presentation.base.ViewSideEffect @@ -11,7 +11,7 @@ class HomeContract { val uiState: LoadState = LoadState.LOADING, val detailListScreenType: DetailListScreenType = DetailListScreenType.RECOMMEND, val bottomSheetState: Boolean = false, - val restaurantData: List = emptyList() + val restaurantData: List = emptyList() ) : ViewState sealed class HomeEvent : ViewEvent { diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantContract.kt b/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantContract.kt index 9fbd3baf..4f77cc45 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantContract.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantContract.kt @@ -1,6 +1,6 @@ package com.everymeal.presentation.ui.restaurant -import com.everymeal.domain.model.restaurant.Restaurant +import com.everymeal.domain.model.restaurant.RestaurantDataEntity import com.everymeal.presentation.base.LoadState import com.everymeal.presentation.base.ViewEvent import com.everymeal.presentation.base.ViewSideEffect @@ -12,7 +12,7 @@ data class DetailRestaurantState( val selectedTabIndex: Int = 0, val isFabClicked: Boolean = false, val getDetailRestaurantState: LoadState = LoadState.LOADING, - val restaurantInfo: Restaurant = Restaurant( + val restaurantInfo: RestaurantDataEntity = RestaurantDataEntity( idx = 0, name = "", address = "", diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantScreen.kt index 1ec3cba0..7b7296bb 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantScreen.kt @@ -41,7 +41,6 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.font.FontWeight @@ -49,9 +48,8 @@ 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 com.everymeal.domain.model.restaurant.Restaurant +import com.everymeal.domain.model.restaurant.RestaurantDataEntity import coil.compose.AsyncImage -import coil.compose.rememberImagePainter import com.everymeal.presentation.R import com.everymeal.presentation.base.LoadState import com.everymeal.presentation.components.EveryMealDialog @@ -252,7 +250,7 @@ fun DetailRestaurantScreen( @OptIn(ExperimentalFoundationApi::class) @Composable fun DetailRestaurantImage( - restaurantInfo : Restaurant + restaurantInfo : RestaurantDataEntity ) { val images = restaurantInfo.images ?: listOf() @@ -296,7 +294,7 @@ fun DetailRestaurantImage( @Composable fun DetailRestaurantMainInfo( - restaurantInfo: Restaurant + restaurantInfo: RestaurantDataEntity ) { Column( modifier = Modifier @@ -409,7 +407,7 @@ fun DetailRestaurantMainInfo( @OptIn(ExperimentalFoundationApi::class) @Composable fun DetailRestaurantTabLayout( - restaurantInfo: Restaurant, + restaurantInfo: RestaurantDataEntity, viewModel: DetailRestaurantViewModel ) { val viewState by viewModel.viewState.collectAsState() @@ -476,7 +474,7 @@ fun DetailRestaurantTabLayout( @Composable fun DetailRestaurantTabInfo( - restaurantInfo: Restaurant, + restaurantInfo: RestaurantDataEntity, modifier: Modifier = Modifier, ) { Column( @@ -538,7 +536,7 @@ fun DetailRestaurantTabInfo( @Composable fun DetailRestaurantTabImage( - restaurantInfo : Restaurant + restaurantInfo : RestaurantDataEntity ) { Column { restaurantInfo.images?.let { images -> diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantViewModel.kt b/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantViewModel.kt index 9702c9b9..ff3443f0 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantViewModel.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantViewModel.kt @@ -1,7 +1,7 @@ package com.everymeal.presentation.ui.restaurant import androidx.lifecycle.viewModelScope -import com.everymeal.domain.model.restaurant.Restaurant +import com.everymeal.domain.model.restaurant.RestaurantDataEntity import com.everymeal.domain.usecase.restaurant.GetDetailRestaurantUseCase import com.everymeal.presentation.base.BaseViewModel import com.everymeal.presentation.base.LoadState @@ -56,7 +56,7 @@ class DetailRestaurantViewModel @Inject constructor( private fun reflectUpdateState( selectedTabIndex: Int = viewState.value.selectedTabIndex, isFabClicked: Boolean = viewState.value.isFabClicked, - restaurantInfo: Restaurant = viewState.value.restaurantInfo, + restaurantInfo: RestaurantDataEntity = viewState.value.restaurantInfo, getDetailRestaurantState: LoadState = viewState.value.getDetailRestaurantState, networkErrorDialog: Boolean = viewState.value.networkErrorDialog ) { diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchContract.kt b/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchContract.kt index 52962d89..f217cacc 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchContract.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchContract.kt @@ -1,6 +1,6 @@ package com.everymeal.presentation.ui.search -import com.everymeal.domain.model.restaurant.Restaurant +import com.everymeal.domain.model.restaurant.RestaurantDataEntity import com.everymeal.presentation.base.ViewEvent import com.everymeal.presentation.base.ViewSideEffect import com.everymeal.presentation.base.ViewState @@ -13,7 +13,7 @@ data class SearchState( val searchQuery: String = "", val searchIsShowHistory: Boolean = true, val searchHistoryItems: List = listOf(), - val searchResultList: List = listOf(), + val searchResultList: List = listOf(), ) : ViewState sealed class SearchEvent : ViewEvent { diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchScreen.kt index e9367581..1474f54e 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/search/SearchScreen.kt @@ -29,7 +29,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavController -import com.everymeal.domain.model.restaurant.Restaurant +import com.everymeal.domain.model.restaurant.RestaurantDataEntity import com.everymeal.presentation.R import com.everymeal.presentation.components.EveryMealRestaurantItem import com.everymeal.presentation.ui.search.history.SearchHistoryList @@ -84,7 +84,7 @@ fun SearchScreen( @Composable fun SearchDetail( modifier: Modifier = Modifier, - searchResultList: List, + searchResultList: List, ) { LazyColumn(modifier = modifier) { itemsIndexed(searchResultList) { index, restaurant ->