Skip to content

Commit b7fbbb7

Browse files
authored
Merge pull request #92 from everymeals/feature/get_detail_restaurant
[feature/get_detail_restaurant] 식당 상세화면 api 연결
2 parents 5a05a02 + 9518059 commit b7fbbb7

File tree

14 files changed

+296
-120
lines changed

14 files changed

+296
-120
lines changed

data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantDataSource.kt

+2
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,6 @@ interface RestaurantDataSource {
1111
group: String? = null,
1212
grade: String? = null,
1313
): Flow<PagingData<RestaurantResponse>>
14+
15+
suspend fun getRestaurantDetail(index: Int): Result<RestaurantResponse>
1416
}

data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantDataSourceImpl.kt

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import androidx.paging.Pager
44
import androidx.paging.PagingConfig
55
import androidx.paging.PagingData
66
import com.everymeal.data.model.restaruant.RestaurantResponse
7+
import com.everymeal.data.model.unwrapData
78
import com.everymeal.data.service.restaurant.RestaurantApi
89
import kotlinx.coroutines.flow.Flow
910
import javax.inject.Inject
@@ -30,4 +31,8 @@ class RestaurantDataSourceImpl @Inject constructor(
3031
pagingSourceFactory = pagingSourceFactory
3132
).flow
3233
}
34+
35+
override suspend fun getRestaurantDetail(index: Int): Result<RestaurantResponse> {
36+
return runCatching { restaurantApi.getRestaurantDetail(index) }.unwrapData()
37+
}
3338
}

data/src/main/java/com/everymeal/data/repository/restaurant/RestaurantRepositoryImpl.kt

+4
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,8 @@ class RestaurantRepositoryImpl @Inject constructor(
2424
pagingData.map { it.toEntity() }
2525
}
2626
}
27+
28+
override suspend fun getRestaurantDetail(index: Int): Result<RestaurantDataEntity> {
29+
return restaurantDataSource.getRestaurantDetail(index).map { it.toEntity() }
30+
}
2731
}

data/src/main/java/com/everymeal/data/service/restaurant/RestaurantApi.kt

+6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.everymeal.data.service.restaurant
22

33
import com.everymeal.data.model.BaseResponse
44
import com.everymeal.data.model.restaruant.GetUnivRestaurantResponse
5+
import com.everymeal.data.model.restaruant.RestaurantResponse
56
import retrofit2.http.GET
67
import retrofit2.http.Path
78
import retrofit2.http.Query
@@ -17,4 +18,9 @@ interface RestaurantApi {
1718
@Query("group") group: String? = null,
1819
@Query("grade") grade: String? = null,
1920
): BaseResponse<GetUnivRestaurantResponse>
21+
22+
@GET("/api/v1/stores/{index}")
23+
suspend fun getRestaurantDetail(
24+
@Path("index") index: Int
25+
): BaseResponse<RestaurantResponse>
2026
}

domain/src/main/java/com/everymeal/domain/repository/restaurant/RestaurantRepository.kt

+4
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,8 @@ interface RestaurantRepository {
1212
group: String? = null,
1313
grade: String? = null,
1414
) : Flow<PagingData<RestaurantDataEntity>>
15+
16+
suspend fun getRestaurantDetail(
17+
index: Int
18+
) : Result<RestaurantDataEntity>
1519
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.everymeal.domain.usecase.restaurant
2+
3+
import com.everymeal.domain.model.restaurant.RestaurantDataEntity
4+
import com.everymeal.domain.repository.restaurant.RestaurantRepository
5+
import javax.inject.Inject
6+
7+
class GetDetailRestaurantUseCase @Inject constructor(
8+
private val restaurantRepository: RestaurantRepository
9+
) {
10+
suspend operator fun invoke(
11+
restaurantIdx: Int,
12+
) : Result<RestaurantDataEntity> {
13+
return restaurantRepository.getRestaurantDetail(restaurantIdx)
14+
}
15+
}

presentation/src/main/java/com/everymeal/presentation/components/EveryMealRestaurantItem.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ import com.everymeal.presentation.ui.theme.Gray700
4343
fun EveryMealRestaurantItem(
4444
restaurant: RestaurantDataEntity,
4545
onLoveClick: () -> Unit = {},
46-
onDetailClick: () -> Unit = {},
46+
onDetailClick: (Int) -> Unit = {},
4747
) {
4848
Column(
4949
modifier = Modifier
@@ -52,7 +52,7 @@ fun EveryMealRestaurantItem(
5252
indication = null,
5353
interactionSource = remember { MutableInteractionSource() }
5454
) {
55-
onDetailClick()
55+
onDetailClick(restaurant.idx)
5656
}
5757
.padding(horizontal = 20.dp)
5858
.background(color = Color.White)

presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,11 @@ class DetailContract {
3030
data class OnClickRating(val rating: Int) : DetailEvent()
3131
object OnDeleteClickRestaurantCategoryType : DetailEvent()
3232
object OnDeleteClickRating : DetailEvent()
33+
data class OnRestaurantDetailClick(val restaurantId: Int) : DetailEvent()
3334
}
3435

3536
sealed class DetailEffect : ViewSideEffect {
36-
37+
data class OnRestaurantClickEffect(val restaurantId: Int) : DetailEffect()
3738
}
3839
}
3940

presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListScreen.kt

+21-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import com.everymeal.presentation.components.EveryMealReportBottomSheetDialog
4141
import com.everymeal.presentation.components.EveryMealRestaurantItem
4242
import com.everymeal.presentation.components.EveryMealSortCategoryBottomSheetDialog
4343
import com.everymeal.presentation.ui.save.SaveTopBar
44+
import com.everymeal.presentation.ui.signup.UnivSelectContract
4445
import com.everymeal.presentation.ui.theme.Grey2
4546
import com.everymeal.presentation.ui.theme.Grey7
4647
import com.everymeal.presentation.ui.theme.Main100
@@ -52,6 +53,7 @@ fun DetailListScreen(
5253
detailListViewModel: DetailListViewModel = hiltViewModel(),
5354
title: String,
5455
navigateToPreviousScreen: () -> Unit,
56+
onDetailRestaurantClick: (Int) -> Unit = {}
5557
) {
5658
val detailListViewState by detailListViewModel.viewState.collectAsState()
5759

@@ -61,6 +63,16 @@ fun DetailListScreen(
6163
detailListViewModel.setEvent(DetailContract.DetailEvent.InitDetailScreen)
6264
}
6365

66+
LaunchedEffect(key1 = detailListViewModel.effect) {
67+
detailListViewModel.effect.collect { effect ->
68+
when(effect) {
69+
is DetailContract.DetailEffect.OnRestaurantClickEffect -> {
70+
onDetailRestaurantClick(effect.restaurantId)
71+
}
72+
}
73+
}
74+
}
75+
6476
if(detailListViewState.sortBottomSheetState) {
6577
EveryMealSortCategoryBottomSheetDialog(
6678
detailListViewState.detailSortCategoryType.title(),
@@ -190,6 +202,9 @@ fun DetailListScreen(
190202
item?.let {
191203
EveryMealRestaurantItem(
192204
restaurant = it,
205+
onDetailClick = { restaurantIdx ->
206+
detailListViewModel.setEvent(DetailContract.DetailEvent.OnRestaurantDetailClick(restaurantIdx))
207+
}
193208
)
194209
Spacer(modifier = Modifier.padding(16.dp))
195210
}
@@ -275,7 +290,12 @@ fun DetailScreenChip(
275290
@Preview
276291
@Composable
277292
fun PreviewDetailListScreen() {
278-
DetailListScreen(title = "맛집") {
293+
DetailListScreen(
294+
title = "맛집",
295+
navigateToPreviousScreen = {
296+
297+
},
298+
) {
279299

280300
}
281301
}

presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListViewModel.kt

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import com.everymeal.presentation.base.BaseViewModel
1010
import com.everymeal.presentation.ui.detail.DetailContract.DetailEvent
1111
import com.everymeal.presentation.ui.detail.DetailContract.DetailState
1212
import com.everymeal.presentation.ui.detail.DetailContract.DetailEffect
13+
import com.everymeal.presentation.ui.signup.UnivSelectContract
1314
import dagger.hilt.android.lifecycle.HiltViewModel
1415
import kotlinx.coroutines.flow.MutableStateFlow
1516
import kotlinx.coroutines.flow.StateFlow
@@ -87,6 +88,9 @@ class DetailListViewModel @Inject constructor(
8788
)
8889
getRestaurantList()
8990
}
91+
is DetailEvent.OnRestaurantDetailClick -> {
92+
sendEffect({ DetailEffect.OnRestaurantClickEffect(event.restaurantId) })
93+
}
9094
}
9195
}
9296

presentation/src/main/java/com/everymeal/presentation/ui/main/MainScreen.kt

+10-3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import com.everymeal.presentation.ui.univfood.UnivFoodScreen
2626
import com.everymeal.presentation.ui.whatfood.WhatFoodScreen
2727

2828
const val DETAIL_SCREEN_TYPE = "detailScreenType"
29+
const val DETAIL_RESTAURANT_IDX = "detailRestaurantIdx"
2930

3031
@Composable
3132
fun MainScreen(
@@ -78,11 +79,17 @@ fun MainScreen(
7879
val detailScreenType = it.arguments?.getString(DETAIL_SCREEN_TYPE) ?: ""
7980
DetailListScreen(
8081
title = detailScreenType,
81-
navigateToPreviousScreen = { navController.popBackStack() }
82+
navigateToPreviousScreen = { navController.popBackStack() },
83+
onDetailRestaurantClick = { detailRestaurantIdx ->
84+
navController.navigate(EveryMealRoute.DETAIL_RESTAURANT.route.plus("/$detailRestaurantIdx"))
85+
}
8286
)
8387
}
84-
composable(route = EveryMealRoute.DETAIL_RESTAURANT.route) {
85-
DetailRestaurantScreen()
88+
composable(route = EveryMealRoute.DETAIL_RESTAURANT.route.plus("/{$DETAIL_RESTAURANT_IDX}")) {
89+
val detailRestaurantIdx = it.arguments?.getString(DETAIL_RESTAURANT_IDX) ?: ""
90+
DetailRestaurantScreen(detailRestaurantIdx.toInt()) {
91+
navController.popBackStack()
92+
}
8693
}
8794
composable(route = EveryMealRoute.SCHOOL_AUTH.route) {
8895
SchoolAuthScreen(

presentation/src/main/java/com/everymeal/presentation/ui/restaurant/DetailRestaurantContract.kt

+19
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,39 @@
11
package com.everymeal.presentation.ui.restaurant
22

3+
import com.everymeal.domain.model.restaurant.RestaurantDataEntity
34
import com.everymeal.presentation.base.LoadState
45
import com.everymeal.presentation.base.ViewEvent
56
import com.everymeal.presentation.base.ViewSideEffect
67
import com.everymeal.presentation.base.ViewState
8+
import com.everymeal.presentation.ui.signup.UnivSelectContract
79

810

911
data class DetailRestaurantState(
1012
val uiState: LoadState = LoadState.SUCCESS,
1113
val selectedTabIndex: Int = 0,
1214
val isFabClicked: Boolean = false,
15+
val getDetailRestaurantState: LoadState = LoadState.LOADING,
16+
val restaurantInfo: RestaurantDataEntity = RestaurantDataEntity(
17+
idx = 0,
18+
name = "",
19+
address = "",
20+
phoneNumber = "",
21+
categoryDetail = "",
22+
distance = 0,
23+
grade = 0f,
24+
reviewCount = 0,
25+
recommendedCount = 0,
26+
images = null,
27+
isLiked = false
28+
),
29+
val networkErrorDialog: Boolean = true,
1330
) : ViewState
1431

1532
sealed class DetailRestaurantEvent : ViewEvent {
1633
data class OnTabSelectedChanged(val selectedTabIndex: Int) : DetailRestaurantEvent()
1734
data class OnFloatingButtonClick(val isFabClicked: Boolean) : DetailRestaurantEvent()
35+
data class InitDetailRestaurantScreen(val restaurantId: Int) : DetailRestaurantEvent()
36+
data class NetworkErrorDialogClicked(val dialogStateChange: Boolean) : DetailRestaurantEvent()
1837
}
1938

2039
sealed class DetailRestaurantEffect : ViewSideEffect {

0 commit comments

Comments
 (0)