From 95223cf19bfcfc62e8e7f075b0ae1109a2a99970 Mon Sep 17 00:00:00 2001 From: sgsk88 Date: Sat, 9 Dec 2023 23:25:16 +0900 Subject: [PATCH 01/11] =?UTF-8?q?[feature/get=5Frestaurant]=20=EC=8B=9D?= =?UTF-8?q?=EB=8B=B9=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=ED=95=98=EB=82=98=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/everymeal/presentation/ui/home/HomeScreen.kt | 1 - 1 file changed, 1 deletion(-) 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 2ec0e705..f574bfae 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 @@ -143,7 +143,6 @@ fun HomeScreen( homeViewModel.setEvent(HomeContract.HomeEvent.BottomSheetStateChange(true)) } HomeCategoryList { - onDetailScreenClickType(it) homeViewModel.setEvent(HomeContract.HomeEvent.OnClickDetailList(it.DetailListScreenType())) } Spacer(modifier = Modifier.padding(10.dp)) From 22020b2edc14fb8b37765a6fb3cc25c74e75316a Mon Sep 17 00:00:00 2001 From: sgsk88 Date: Sun, 10 Dec 2023 22:06:51 +0900 Subject: [PATCH 02/11] =?UTF-8?q?[feature/get=5Frestaurant]=20API,=20DTO?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../everymeal_android/di/RepositoryModule.kt | 17 ++++++ .../restaurant/RestaurantDataSource.kt | 4 ++ .../restaurant/RestaurantDataSourceImpl.kt | 9 +++ .../restaruant/GetUnivRestaurantResponse.kt | 55 +++++++++++++++++++ .../restaurant/RestaurantRepositoryImpl.kt | 4 ++ .../data/service/restaurant/RestaurantApi.kt | 20 +++++++ .../restaurant/RestaurantRepository.kt | 4 ++ 7 files changed, 113 insertions(+) create mode 100644 data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantDataSource.kt create mode 100644 data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantDataSourceImpl.kt create mode 100644 data/src/main/java/com/everymeal/data/model/restaruant/GetUnivRestaurantResponse.kt create mode 100644 data/src/main/java/com/everymeal/data/repository/restaurant/RestaurantRepositoryImpl.kt create mode 100644 data/src/main/java/com/everymeal/data/service/restaurant/RestaurantApi.kt create mode 100644 domain/src/main/java/com/everymeal/domain/repository/restaurant/RestaurantRepository.kt 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..9121c1b9 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 @@ -6,12 +6,17 @@ import com.everymeal.data.datasource.local.LocalDataSource 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.datasource.restaurant.RestaurantDataSource +import com.everymeal.data.datasource.restaurant.RestaurantDataSourceImpl import com.everymeal.data.repository.local.LocalRepositoryImpl import com.everymeal.data.repository.DefaultAuthRepository import com.everymeal.data.repository.onboarding.OnboardingRepositoryImpl +import com.everymeal.data.repository.restaurant.RestaurantRepositoryImpl import com.everymeal.domain.repository.local.LocalRepository import com.everymeal.domain.repository.auth.AuthRepository import com.everymeal.domain.repository.onboarding.OnboardingRepository +import com.everymeal.domain.repository.restaurant.RestaurantRepository +import com.everymeal.presentation.ui.home.Restaurant import dagger.Binds import dagger.Module import dagger.hilt.InstallIn @@ -57,4 +62,16 @@ abstract class RepositoryModule { abstract fun bindAuthRepository( defaultAuthRepository: DefaultAuthRepository ): AuthRepository + + @Singleton + @Binds + abstract fun bindRestaurantDataSource( + restaurantDataSourceImpl: RestaurantDataSourceImpl + ): RestaurantDataSource + + @Singleton + @Binds + abstract fun bindRestaurantRepository( + restaurantRepositoryImpl: RestaurantRepositoryImpl + ): RestaurantRepository } diff --git a/data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantDataSource.kt b/data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantDataSource.kt new file mode 100644 index 00000000..6166fc28 --- /dev/null +++ b/data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantDataSource.kt @@ -0,0 +1,4 @@ +package com.everymeal.data.datasource.restaurant + +interface RestaurantDataSource { +} \ No newline at end of file diff --git a/data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantDataSourceImpl.kt b/data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantDataSourceImpl.kt new file mode 100644 index 00000000..d2ea47e8 --- /dev/null +++ b/data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantDataSourceImpl.kt @@ -0,0 +1,9 @@ +package com.everymeal.data.datasource.restaurant + +import javax.inject.Inject + +class RestaurantDataSourceImpl @Inject constructor( + +) : RestaurantDataSource { + +} \ No newline at end of file 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 new file mode 100644 index 00000000..b20fde77 --- /dev/null +++ b/data/src/main/java/com/everymeal/data/model/restaruant/GetUnivRestaurantResponse.kt @@ -0,0 +1,55 @@ +package com.everymeal.data.model.restaruant + +import kotlinx.serialization.Serializable + +@Serializable +data class GetUnivRestaurantResponse( + val content: PagignRestaurantResponse +) + +@Serializable +data class PagignRestaurantResponse( + val content: List, + val pageable: Pageable, + val totalPages: Int, + val totalElements: Int, + val last: Boolean, + val size: Int, + val number: Int, + val sort: Sort, + val numberOfElements: Int, + val first: Boolean, + val empty: Boolean +) + +@Serializable +data class RestaurantResponse( + val idx: Int, + val name: String, + val address: String, + val phoneNumber: String, + val categoryDetail: String, + val distance: Int, + val grade: Int, + val reviewCount: Int, + val recommendedCount: Int, + val images: List?, + val isLiked: Boolean +) + +@Serializable +data class Pageable( + val sort: Sort, + val offset: Int, + val pageNumber: Int, + val pageSize: Int, + val paged: Boolean, + val unpaged: Boolean +) + +@Serializable +data class Sort( + val empty: Boolean, + val sorted: Boolean, + val unsorted: Boolean +) \ No newline at end of file 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 new file mode 100644 index 00000000..42a7c0ea --- /dev/null +++ b/data/src/main/java/com/everymeal/data/repository/restaurant/RestaurantRepositoryImpl.kt @@ -0,0 +1,4 @@ +package com.everymeal.data.repository.restaurant + +class RestaurantRepositoryImpl { +} \ No newline at end of file diff --git a/data/src/main/java/com/everymeal/data/service/restaurant/RestaurantApi.kt b/data/src/main/java/com/everymeal/data/service/restaurant/RestaurantApi.kt new file mode 100644 index 00000000..d52ef719 --- /dev/null +++ b/data/src/main/java/com/everymeal/data/service/restaurant/RestaurantApi.kt @@ -0,0 +1,20 @@ +package com.everymeal.data.service.restaurant + +import com.everymeal.data.model.BaseResponse +import com.everymeal.data.model.restaruant.GetUnivRestaurantResponse +import retrofit2.http.GET +import retrofit2.http.Path +import retrofit2.http.Query + +interface RestaurantApi { + + @GET("/api/v1/store/{campusIdx}") + suspend fun getUnivRestaurant( + @Path("campusIdx") campusIdx: Int, + @Query("offset") offset: Int, + @Query("limit") limit: Int, + @Query("order") order: String, + @Query("group") group: String? = null, + @Query("grade") grade: String? = null, + ): BaseResponse +} \ No newline at end of file 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 new file mode 100644 index 00000000..cf0e0bdb --- /dev/null +++ b/domain/src/main/java/com/everymeal/domain/repository/restaurant/RestaurantRepository.kt @@ -0,0 +1,4 @@ +package com.everymeal.domain.repository.restaurant + +interface RestaurantRepository { +} \ No newline at end of file From 7ae84e893fbacaa1ef20e118925c9270364e15dd Mon Sep 17 00:00:00 2001 From: sgsk88 Date: Sun, 10 Dec 2023 22:52:38 +0900 Subject: [PATCH 03/11] =?UTF-8?q?[feature/get=5Frestaurant]=20=ED=95=99?= =?UTF-8?q?=EA=B5=90=20=EA=B7=BC=EC=B2=98=20=EC=8B=9D=EB=8B=B9=20PagingSou?= =?UTF-8?q?rce=20=EA=B5=AC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- data/build.gradle.kts | 4 ++ .../restaurant/RestaurantDataSource.kt | 10 ++++ .../restaurant/RestaurantDataSourceImpl.kt | 28 ++++++++++- .../restaurant/RestaurantPagingSource.kt | 50 +++++++++++++++++++ .../restaruant/GetUnivRestaurantResponse.kt | 24 ++++++--- .../restaurant/RestaurantRepositoryImpl.kt | 24 ++++++++- domain/build.gradle.kts | 2 + .../restaurant/GetUnivRestaurantEntity.kt | 20 ++++++++ .../restaurant/RestaurantRepository.kt | 11 ++++ .../usecase/restaurant/GetUnivRestaurant.kt | 20 ++++++++ gradle/libs.versions.toml | 8 +++ presentation/build.gradle.kts | 4 ++ 12 files changed, 196 insertions(+), 9 deletions(-) create mode 100644 data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantPagingSource.kt create mode 100644 domain/src/main/java/com/everymeal/domain/model/restaurant/GetUnivRestaurantEntity.kt create mode 100644 domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetUnivRestaurant.kt diff --git a/data/build.gradle.kts b/data/build.gradle.kts index 437b388b..f4933718 100644 --- a/data/build.gradle.kts +++ b/data/build.gradle.kts @@ -44,4 +44,8 @@ dependencies { //DataStore implementation(libs.data.store) + + // Paging + implementation(libs.paging.compose) + implementation(libs.paging.runtime) } \ No newline at end of file diff --git a/data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantDataSource.kt b/data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantDataSource.kt index 6166fc28..54c51f59 100644 --- a/data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantDataSource.kt +++ b/data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantDataSource.kt @@ -1,4 +1,14 @@ package com.everymeal.data.datasource.restaurant +import androidx.paging.PagingData +import com.everymeal.data.model.restaruant.RestaurantResponse +import kotlinx.coroutines.flow.Flow + interface RestaurantDataSource { + suspend fun getUnivRestaurant( + campusIdx: Int, + order: String, + group: String? = null, + grade: String? = null, + ): Flow> } \ No newline at end of file diff --git a/data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantDataSourceImpl.kt b/data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantDataSourceImpl.kt index d2ea47e8..dc76f05d 100644 --- a/data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantDataSourceImpl.kt +++ b/data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantDataSourceImpl.kt @@ -1,9 +1,33 @@ package com.everymeal.data.datasource.restaurant +import androidx.paging.Pager +import androidx.paging.PagingConfig +import androidx.paging.PagingData +import com.everymeal.data.model.restaruant.RestaurantResponse +import com.everymeal.data.service.restaurant.RestaurantApi +import kotlinx.coroutines.flow.Flow import javax.inject.Inject -class RestaurantDataSourceImpl @Inject constructor( +const val PAGING_SIZE = 20 +const val STARTING_PAGE_INDEX = 0 +class RestaurantDataSourceImpl @Inject constructor( + private val restaurantApi: RestaurantApi ) : RestaurantDataSource { - + override suspend fun getUnivRestaurant( + campusIdx: Int, + order: String, + group: String?, + grade: String? + ) : Flow> { + val pagingSourceFactory = { RestaurantPagingSource(restaurantApi, campusIdx, order, group, grade) } + return Pager( + config = PagingConfig( + initialLoadSize = PAGING_SIZE, + pageSize = PAGING_SIZE, + enablePlaceholders = false, + ), + pagingSourceFactory = pagingSourceFactory + ).flow + } } \ No newline at end of file diff --git a/data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantPagingSource.kt b/data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantPagingSource.kt new file mode 100644 index 00000000..c73ce1a3 --- /dev/null +++ b/data/src/main/java/com/everymeal/data/datasource/restaurant/RestaurantPagingSource.kt @@ -0,0 +1,50 @@ +package com.everymeal.data.datasource.restaurant + +import androidx.paging.PagingSource +import androidx.paging.PagingState +import com.everymeal.data.model.restaruant.RestaurantResponse +import com.everymeal.data.service.restaurant.RestaurantApi +import retrofit2.HttpException +import java.io.IOException + +class RestaurantPagingSource ( + private val restaurantApi: RestaurantApi, + private val campusIdx: Int, + private val order: String, + private val group: String?, + private val grade: String? +) : PagingSource() { + + override fun getRefreshKey(state: PagingState): Int? { + return state.anchorPosition?.let { anchorPosition -> + state.closestPageToPosition(anchorPosition)?.prevKey?.plus(1) + ?: state.closestPageToPosition(anchorPosition)?.nextKey?.minus(1) + } + } + + override suspend fun load(params: LoadParams): LoadResult { + val position = params.key ?: STARTING_PAGE_INDEX + + return try { + val response = restaurantApi.getUnivRestaurant( + campusIdx = campusIdx, + order = order, + group = group, + grade = grade, + offset = position, + limit = PAGING_SIZE + ) + val restaurants = response.data.content + LoadResult.Page( + data = restaurants, + prevKey = if (position == STARTING_PAGE_INDEX) null else position - 1, + nextKey = if (restaurants.isEmpty()) null else position + 1 + ) + } catch (exception: IOException) { + LoadResult.Error(exception) + } catch (exception: HttpException) { + LoadResult.Error(exception) + } + } + +} \ No newline at end of file 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 b20fde77..2c498c46 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,14 +1,10 @@ package com.everymeal.data.model.restaruant +import com.everymeal.domain.model.restaurant.RestaurantDataEntity import kotlinx.serialization.Serializable @Serializable data class GetUnivRestaurantResponse( - val content: PagignRestaurantResponse -) - -@Serializable -data class PagignRestaurantResponse( val content: List, val pageable: Pageable, val totalPages: Int, @@ -52,4 +48,20 @@ data class Sort( val empty: Boolean, val sorted: Boolean, val unsorted: Boolean -) \ No newline at end of file +) + +fun RestaurantResponse.toEntity(): RestaurantDataEntity { + return RestaurantDataEntity( + idx = this.idx, + name = this.name, + address = this.address, + phoneNumber = this.phoneNumber, + categoryDetail = this.categoryDetail, + distance = this.distance, + grade = this.grade, + reviewCount = this.reviewCount, + recommendedCount = this.recommendedCount, + images = this.images, + isLiked = this.isLiked + ) +} \ No newline at end of file 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 42a7c0ea..752e0277 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,4 +1,26 @@ package com.everymeal.data.repository.restaurant -class RestaurantRepositoryImpl { +import androidx.paging.PagingData +import com.everymeal.data.datasource.restaurant.RestaurantDataSource +import com.everymeal.domain.model.restaurant.RestaurantDataEntity +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 + +class RestaurantRepositoryImpl( + private val restaurantDataSource: RestaurantDataSource +) : RestaurantRepository { + override suspend fun getUnivRestaurant( + campusIdx: Int, + order: String, + group: String?, + grade: String? + ) : Flow> { + return restaurantDataSource.getUnivRestaurant(campusIdx, order, group, grade) + .map { pagingData -> + pagingData.map { it.toEntity() } + } + } } \ No newline at end of file diff --git a/domain/build.gradle.kts b/domain/build.gradle.kts index 4403f376..e3f42c70 100644 --- a/domain/build.gradle.kts +++ b/domain/build.gradle.kts @@ -14,4 +14,6 @@ dependencies { // Coroutines implementation(libs.kotlin.coroutines) + + implementation("androidx.paging:paging-common:3.2.0-rc01") } 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..44696cb8 --- /dev/null +++ b/domain/src/main/java/com/everymeal/domain/model/restaurant/GetUnivRestaurantEntity.kt @@ -0,0 +1,20 @@ +package com.everymeal.domain.model.restaurant + +data class GetUnivRestaurantEntity( + val data: List +) + +data class RestaurantDataEntity( + val idx: Int, + val name: String, + val address: String, + val phoneNumber: String, + val categoryDetail: String, + val distance: Int, + val grade: Int, + val reviewCount: Int, + val recommendedCount: Int, + val images: List?, + val isLiked: Boolean +) + 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 cf0e0bdb..9038d73e 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,4 +1,15 @@ package com.everymeal.domain.repository.restaurant +import androidx.paging.PagingData +import com.everymeal.domain.model.restaurant.RestaurantDataEntity +import kotlinx.coroutines.flow.Flow + interface RestaurantRepository { + + suspend fun getUnivRestaurant( + campusIdx: Int, + order: String, + group: String? = null, + grade: String? = null, + ) : Flow> } \ No newline at end of file diff --git a/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetUnivRestaurant.kt b/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetUnivRestaurant.kt new file mode 100644 index 00000000..67e52ba7 --- /dev/null +++ b/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetUnivRestaurant.kt @@ -0,0 +1,20 @@ +package com.everymeal.domain.usecase.restaurant + +import androidx.paging.PagingData +import com.everymeal.domain.model.restaurant.RestaurantDataEntity +import com.everymeal.domain.repository.restaurant.RestaurantRepository +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject + +class GetUnivRestaurant @Inject constructor( + private val restaurantRepository: RestaurantRepository +) { + suspend operator fun invoke( + campusIdx: Int, + order: String, + group: String?, + grade: String? + ) : Flow> { + return restaurantRepository.getUnivRestaurant(campusIdx, order, group, grade) + } +} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7bbae4f2..f788ebfa 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,6 +22,9 @@ accompanist = "0.33.0-alpha" data-store = "1.0.0" kotlin-coroutines = "1.7.3" +paging-compose = "3.2.0-rc01" +paging-runtime = "3.1.0" + [libraries] agp = { module = "com.android.tools.build:gradle", version.ref = "agp" } coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coil-compose" } @@ -78,6 +81,11 @@ data-store = { module = "androidx.datastore:datastore-preferences", version.ref #kotlin-coroutines kotlin-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlin-coroutines" } +#Paging +paging-runtime = { module = "androidx.paging:paging-runtime", version = "paging-runtime" } +paging-compose = { module = "androidx.paging:paging-compose", version = "paging-compose" } +paging-common = { module = "androidx.paging:paging-common", version = "paging-compose" } + [plugins] androidApplication = { id = "com.android.application", version.ref = "agp" } kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } diff --git a/presentation/build.gradle.kts b/presentation/build.gradle.kts index b1d59c11..ab502ab1 100644 --- a/presentation/build.gradle.kts +++ b/presentation/build.gradle.kts @@ -87,4 +87,8 @@ dependencies { // Coil implementation(libs.coil.compose) + + // Paging + implementation(libs.paging.compose) + implementation(libs.paging.runtime) } From e7bb087b30e98e033c41403aac9a8b9295438905 Mon Sep 17 00:00:00 2001 From: sgsk88 Date: Sat, 6 Jan 2024 15:45:09 +0900 Subject: [PATCH 04/11] =?UTF-8?q?[feature/get=5Frestaurant]=20Column=20->?= =?UTF-8?q?=20Lazy=20=EB=B3=80=EA=B2=BD=20(#88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/detail/DetailListScreen.kt | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) 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 b19db241..6a418da0 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 @@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface @@ -103,23 +104,19 @@ fun DetailListScreen( ) } - Column( - modifier = Modifier - .fillMaxSize() - .background(color = Color.White), - ) { - Scaffold( - topBar = { - SaveTopBar(title = title) { - navigateToPreviousScreen() - } + Scaffold( + topBar = { + SaveTopBar(title = title) { + navigateToPreviousScreen() } - ) { innerPadding -> - Column( - modifier = Modifier - .padding(innerPadding) - .padding(horizontal = 20.dp), - ) { + } + ) { innerPadding -> + LazyColumn( + modifier = Modifier + .padding(innerPadding) + .padding(horizontal = 20.dp), + ) { + item { Row { DetailScreenChip( title = detailListViewState.detailSortCategoryType.title(), From 87e950d169f07f7df582554e76f6fee0afaafdc0 Mon Sep 17 00:00:00 2001 From: sgsk88 Date: Sat, 6 Jan 2024 16:33:40 +0900 Subject: [PATCH 05/11] =?UTF-8?q?[feature/get=5Frestaurant]=20Paging=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../everymeal_android/di/NetworkModule.kt | 10 ++ .../restaruant/GetUnivRestaurantResponse.kt | 2 +- .../restaurant/RestaurantRepositoryImpl.kt | 3 +- .../data/service/restaurant/RestaurantApi.kt | 2 +- .../restaurant/GetUnivRestaurantEntity.kt | 2 +- ...taurant.kt => GetUnivRestaurantUseCase.kt} | 2 +- .../components/EveryMealRestaurantItem.kt | 164 +++++++++--------- .../ui/detail/DetailListContract.kt | 1 + .../ui/detail/DetailListScreen.kt | 20 +++ .../ui/detail/DetailListViewModel.kt | 28 ++- .../presentation/ui/home/HomeScreen.kt | 52 ++++-- 11 files changed, 181 insertions(+), 105 deletions(-) rename domain/src/main/java/com/everymeal/domain/usecase/restaurant/{GetUnivRestaurant.kt => GetUnivRestaurantUseCase.kt} (92%) 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..fecafbfa 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.restaurant.RestaurantApi import com.everymeal.everymeal_android.BuildConfig import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory import dagger.Module @@ -11,6 +12,7 @@ import dagger.hilt.components.SingletonComponent import kotlinx.serialization.json.Json import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor import retrofit2.Retrofit import java.util.concurrent.TimeUnit import javax.inject.Singleton @@ -26,7 +28,9 @@ object NetworkModule { @Provides @Singleton fun provideClient(): OkHttpClient { + val interceptor = HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY) return OkHttpClient.Builder() + .addInterceptor(interceptor) .connectTimeout(100, TimeUnit.SECONDS) .readTimeout(100, TimeUnit.SECONDS) .build() @@ -53,4 +57,10 @@ object NetworkModule { fun provideAuthApi(retrofit: Retrofit): AuthApi { return retrofit.create(AuthApi::class.java) } + + @Provides + @Singleton + fun provideRestaurantApi(retrofit: Retrofit): RestaurantApi { + return retrofit.create(RestaurantApi::class.java) + } } \ No newline at end of file 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 2c498c46..f4801fe6 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 @@ -26,7 +26,7 @@ data class RestaurantResponse( val phoneNumber: String, val categoryDetail: String, val distance: Int, - val grade: Int, + val grade: Float, val reviewCount: Int, val recommendedCount: Int, val images: List?, 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 752e0277..56366a2e 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 @@ -8,8 +8,9 @@ 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( +class RestaurantRepositoryImpl @Inject constructor( private val restaurantDataSource: RestaurantDataSource ) : RestaurantRepository { override suspend fun getUnivRestaurant( diff --git a/data/src/main/java/com/everymeal/data/service/restaurant/RestaurantApi.kt b/data/src/main/java/com/everymeal/data/service/restaurant/RestaurantApi.kt index d52ef719..5ea42b0d 100644 --- a/data/src/main/java/com/everymeal/data/service/restaurant/RestaurantApi.kt +++ b/data/src/main/java/com/everymeal/data/service/restaurant/RestaurantApi.kt @@ -8,7 +8,7 @@ import retrofit2.http.Query interface RestaurantApi { - @GET("/api/v1/store/{campusIdx}") + @GET("/api/v1/stores/{campusIdx}") suspend fun getUnivRestaurant( @Path("campusIdx") campusIdx: Int, @Query("offset") offset: Int, 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 44696cb8..0ef6ab29 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 @@ -11,7 +11,7 @@ data class RestaurantDataEntity( val phoneNumber: String, val categoryDetail: String, val distance: Int, - val grade: Int, + val grade: Float, val reviewCount: Int, val recommendedCount: Int, val images: List?, diff --git a/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetUnivRestaurant.kt b/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetUnivRestaurantUseCase.kt similarity index 92% rename from domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetUnivRestaurant.kt rename to domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetUnivRestaurantUseCase.kt index 67e52ba7..4257fb08 100644 --- a/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetUnivRestaurant.kt +++ b/domain/src/main/java/com/everymeal/domain/usecase/restaurant/GetUnivRestaurantUseCase.kt @@ -6,7 +6,7 @@ import com.everymeal.domain.repository.restaurant.RestaurantRepository import kotlinx.coroutines.flow.Flow import javax.inject.Inject -class GetUnivRestaurant @Inject constructor( +class GetUnivRestaurantUseCase @Inject constructor( private val restaurantRepository: RestaurantRepository ) { suspend operator fun invoke( 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 75927f96..c81550a0 100644 --- a/presentation/src/main/java/com/everymeal/presentation/components/EveryMealRestaurantItem.kt +++ b/presentation/src/main/java/com/everymeal/presentation/components/EveryMealRestaurantItem.kt @@ -30,6 +30,8 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import 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.home.Restaurant @@ -41,9 +43,9 @@ import com.everymeal.presentation.ui.theme.Gray700 @Composable fun EveryMealRestaurantItem( - restaurant: Restaurant, - onLoveClick: () -> Unit, - onDetailClick: () -> Unit, + restaurant: RestaurantDataEntity, + onLoveClick: () -> Unit = {}, + onDetailClick: () -> Unit = {}, ) { Column( modifier = Modifier @@ -69,7 +71,7 @@ fun EveryMealRestaurantItem( @Composable fun RestaurantTitle( modifier: Modifier = Modifier, - restaurant: Restaurant, + restaurant: RestaurantDataEntity, onLoveClick: () -> Unit, ) { Row( @@ -88,7 +90,7 @@ fun RestaurantTitle( .clip(RoundedCornerShape(4.dp)) .background(color = Gray300) .padding(vertical = 3.dp, horizontal = 6.dp), - text = restaurant.category, + text = restaurant.name, color = Gray600, fontSize = 12.sp ) @@ -99,7 +101,7 @@ fun RestaurantTitle( @Composable fun RestaurantLoveCount( - restaurant: Restaurant, + restaurant: RestaurantDataEntity, onLoveClick: () -> Unit, ) { Column( @@ -115,7 +117,7 @@ fun RestaurantLoveCount( contentDescription = stringResource(R.string.icon_star), ) Text( - text = "${restaurant.loveCount}", + text = "${restaurant.recommendedCount}", color = Gray500, fontSize = 12.sp, fontWeight = FontWeight.Medium, @@ -124,7 +126,7 @@ fun RestaurantLoveCount( } @Composable -fun RestaurantRating(restaurant: Restaurant) { +fun RestaurantRating(restaurant: RestaurantDataEntity) { Row( modifier = Modifier .width(100.dp), @@ -136,7 +138,7 @@ fun RestaurantRating(restaurant: Restaurant) { ) Text( modifier = Modifier.padding(start = 2.dp), - text = restaurant.rating.toString(), + text = restaurant.grade.toString(), color = Gray700, fontSize = 12.sp, fontWeight = FontWeight.Medium, @@ -153,103 +155,105 @@ fun RestaurantRating(restaurant: Restaurant) { } @Composable -fun RestaurantImage(restaurant: Restaurant) { +fun RestaurantImage(restaurant: RestaurantDataEntity) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween ) { - when { - restaurant.image.size == 3 -> { - restaurant.image.forEachIndexed { index, image -> - Image( + restaurant.images?.let { + when { + restaurant.images?.size == 3 -> { + restaurant.images?.forEachIndexed { index, image -> + AsyncImage( + modifier = Modifier + .weight(1f) + .aspectRatio(1f) + .clip(RoundedCornerShape(8.dp)), + model = image, + contentDescription = null + ) + if(index != 2) { + Spacer(modifier = Modifier.padding(end = 6.dp)) + } + } + } + + restaurant.images?.size == 2 -> { + restaurant.images?.forEachIndexed { index, image -> + AsyncImage( + modifier = Modifier + .weight(1f) + .aspectRatio(1f) + .clip(RoundedCornerShape(8.dp)), + model = image, + contentDescription = null + ) + if(index != 1) { + Spacer(modifier = Modifier.padding(end = 6.dp)) + } + } + Spacer(modifier = Modifier.weight(1f)) + } + + restaurant.images?.size == 1 -> { + AsyncImage( modifier = Modifier .weight(1f) .aspectRatio(1f) .clip(RoundedCornerShape(8.dp)), - painter = painterResource(id = image), + model = restaurant.images!![0], contentDescription = null ) - if(index != 2) { - Spacer(modifier = Modifier.padding(end = 6.dp)) - } + Spacer(modifier = Modifier + .weight(2f) + .padding(end = 6.dp) + ) } - } - restaurant.image.size == 2 -> { - restaurant.image.forEachIndexed { index, image -> - Image( + restaurant.images?.size!! > 3 -> { + AsyncImage( modifier = Modifier .weight(1f) .aspectRatio(1f) .clip(RoundedCornerShape(8.dp)), - painter = painterResource(id = image), + model = restaurant.images!![0], contentDescription = null ) - if(index != 1) { - Spacer(modifier = Modifier.padding(end = 6.dp)) - } - } - Spacer(modifier = Modifier.weight(1f)) - } - - restaurant.image.size == 1 -> { - Image( - modifier = Modifier - .weight(1f) - .aspectRatio(1f) - .clip(RoundedCornerShape(8.dp)), - painter = painterResource(id = restaurant.image[0]), - contentDescription = null - ) - Spacer(modifier = Modifier - .weight(2f) - .padding(end = 6.dp) - ) - } - - restaurant.image.size > 3 -> { - Image( - modifier = Modifier - .weight(1f) - .aspectRatio(1f) - .clip(RoundedCornerShape(8.dp)), - painter = painterResource(restaurant.image[0]), - contentDescription = null - ) - Spacer(modifier = Modifier.padding(end = 6.dp)) - Image( - modifier = Modifier - .weight(1f) - .aspectRatio(1f) - .clip(RoundedCornerShape(8.dp)), - painter = painterResource(restaurant.image[1]), - contentDescription = null - ) - Spacer(modifier = Modifier.padding(end = 6.dp)) - Box( - modifier = Modifier - .weight(1f) - .aspectRatio(1f) - ) { - Image( + Spacer(modifier = Modifier.padding(end = 6.dp)) + AsyncImage( modifier = Modifier + .weight(1f) .aspectRatio(1f) - .fillMaxSize(), - painter = painterResource(id = restaurant.image[2]), + .clip(RoundedCornerShape(8.dp)), + model = restaurant.images!![0], contentDescription = null ) + Spacer(modifier = Modifier.padding(end = 6.dp)) Box( modifier = Modifier - .matchParentSize() - .clip(RoundedCornerShape(8.dp)) - .background(Color.Black.copy(alpha = 0.5f)), - contentAlignment = Alignment.Center + .weight(1f) + .aspectRatio(1f) ) { - Text( - text = "+${restaurant.image.size - 2}", - color = Color.White, - fontSize = 14.sp + AsyncImage( + modifier = Modifier + .aspectRatio(1f) + .fillMaxSize(), + model = restaurant.images!![0], + contentDescription = null ) + Box( + modifier = Modifier + .matchParentSize() + .clip(RoundedCornerShape(8.dp)) + .background(Color.Black.copy(alpha = 0.5f)), + contentAlignment = Alignment.Center + ) { + Text( + text = "+${restaurant.reviewCount - 2}", + color = Color.White, + fontSize = 14.sp + ) + } } } } diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt index 29d4787e..887363d7 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt @@ -19,6 +19,7 @@ class DetailContract { ) : ViewState sealed class DetailEvent : ViewEvent { + object InitDetailScreen : DetailEvent() data class SortBottomSheetStateChange(val sortBottomSheetState: Boolean) : DetailEvent() data class MealRatingBottomSheetStateChange(val mealRatingBottomSheetState: Boolean) : DetailEvent() data class ReportBottomSheetStateChange(val reportBottomSheetState: Boolean) : DetailEvent() 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 6a418da0..3d3513fd 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 @@ -16,6 +16,7 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.remember @@ -27,10 +28,14 @@ import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp 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.presentation.R import com.everymeal.presentation.components.EveryMealCategoryRatingBottomSheetDialog import com.everymeal.presentation.components.EveryMealDetailReportBottomSheetDialog 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.theme.Grey2 @@ -45,6 +50,12 @@ fun DetailListScreen( ) { val detailListViewState by detailListViewModel.viewState.collectAsState() + val pagingRestaurantList : LazyPagingItems = detailListViewModel.restaurantItems.collectAsLazyPagingItems() + + LaunchedEffect(Unit) { + detailListViewModel.setEvent(DetailContract.DetailEvent.InitDetailScreen) + } + if(detailListViewState.sortBottomSheetState) { EveryMealSortCategoryBottomSheetDialog( detailListViewState.detailSortCategoryType.title(), @@ -142,6 +153,15 @@ fun DetailListScreen( ) } } + + items(pagingRestaurantList.itemCount) { index -> + val item = pagingRestaurantList[index] + item?.let { + EveryMealRestaurantItem( + restaurant = it, + ) + } + } } } } 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 9af0d51e..b8909d58 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 @@ -1,19 +1,35 @@ 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.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 dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch import javax.inject.Inject +@HiltViewModel class DetailListViewModel @Inject constructor( - + private val getUnivRestaurantUseCase: GetUnivRestaurantUseCase ): BaseViewModel( DetailState() ) { + private val _restaurantItems : MutableStateFlow> = MutableStateFlow(value = PagingData.empty()) + val restaurantItems : StateFlow> = _restaurantItems.asStateFlow() override fun handleEvents(event: DetailEvent) { when (event) { + is DetailEvent.InitDetailScreen -> { + getRestaurantList() + } is DetailEvent.OnClickDetailListCategoryType -> { reflectUpdateState( detailSortCategoryType = event.detailSortCategoryType @@ -57,6 +73,16 @@ class DetailListViewModel @Inject constructor( } } + private fun getRestaurantList() { + viewModelScope.launch { + getUnivRestaurantUseCase(1, "name", null, null) + .cachedIn(viewModelScope) + .collect { + _restaurantItems.emit(it) + } + } + } + private fun reflectUpdateState( detailSortCategoryType: DetailSortCategoryType = viewState.value.detailSortCategoryType, sortBottomSheetState: Boolean = viewState.value.sortBottomSheetState, 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 f574bfae..6662bd01 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,6 +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.presentation.R import com.everymeal.presentation.components.EveryMealLineButton import com.everymeal.presentation.components.EveryMealMainBottomSheetDialog @@ -59,28 +60,41 @@ fun HomeScreen( onDetailRestaurantClick : () -> Unit, ) { val items = listOf( - Restaurant( - name = "슈니", - category = "한식", - image = listOf( - R.drawable.food_ex_1, + RestaurantDataEntity( + idx = 386, + name = "히포 브런치하우스", + address = "서울 마포구 연남동 487-34", + phoneNumber = "010-3796-3176", + categoryDetail = "카페", + distance = 1721, + grade = 0.0F, + reviewCount = 5, + recommendedCount = 5, + images = listOf( + "store/ea9be6e1-c5cb-4772-a5a8-15bb89b604a0", + "store/ea9be6e1-c5cb-4772-a5a8-15bb89b604a0", + "store/ea9be6e1-c5cb-4772-a5a8-15bb89b604a0", + "store/ea9be6e1-c5cb-4772-a5a8-15bb89b604a0", ), - rating = 4.5, - reviewCount = 100, - loveCount = 100, + isLiked = false, ), - Restaurant( - name = "왕가주방", - category = "중식", - image = listOf( - R.drawable.food_ex_1, - R.drawable.food_ex_2, - R.drawable.food_ex_3, - R.drawable.food_ex_3, + RestaurantDataEntity( + idx = 386, + name = "히포 브런치하우스", + address = "서울 마포구 연남동 487-34", + phoneNumber = "010-3796-3176", + categoryDetail = "카페", + distance = 1721, + grade = 0.0F, + reviewCount = 5, + recommendedCount = 5, + images = listOf( + "store/ea9be6e1-c5cb-4772-a5a8-15bb89b604a0", + "store/ea9be6e1-c5cb-4772-a5a8-15bb89b604a0", + "store/ea9be6e1-c5cb-4772-a5a8-15bb89b604a0", + "store/ea9be6e1-c5cb-4772-a5a8-15bb89b604a0", ), - rating = 4.5, - reviewCount = 100, - loveCount = 100, + isLiked = false, ), ) From a68299f68f933490e3e077d47f8e2daf1faa8629 Mon Sep 17 00:00:00 2001 From: sgsk88 Date: Sat, 6 Jan 2024 17:56:55 +0900 Subject: [PATCH 06/11] =?UTF-8?q?[feature/get=5Frestaurant]=20sort=20?= =?UTF-8?q?=EC=A0=95=EB=A0=AC=20=EA=B5=AC=ED=98=84=20(#88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/EveryMealRestaurantItem.kt | 7 +++---- .../ui/detail/DetailListContract.kt | 8 ++++++++ .../ui/detail/DetailListScreen.kt | 13 ++++++++---- .../ui/detail/DetailListViewModel.kt | 20 +++++++++++++------ 4 files changed, 34 insertions(+), 14 deletions(-) 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 c81550a0..796496e1 100644 --- a/presentation/src/main/java/com/everymeal/presentation/components/EveryMealRestaurantItem.kt +++ b/presentation/src/main/java/com/everymeal/presentation/components/EveryMealRestaurantItem.kt @@ -23,7 +23,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector -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 @@ -34,7 +33,6 @@ 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.home.Restaurant import com.everymeal.presentation.ui.theme.EveryMeal_AndroidTheme import com.everymeal.presentation.ui.theme.Gray300 import com.everymeal.presentation.ui.theme.Gray500 @@ -83,6 +81,7 @@ fun RestaurantTitle( color = Color.Black, fontSize = 17.sp, fontWeight = FontWeight.SemiBold, + maxLines = 1 ) Text( modifier = Modifier @@ -90,7 +89,7 @@ fun RestaurantTitle( .clip(RoundedCornerShape(4.dp)) .background(color = Gray300) .padding(vertical = 3.dp, horizontal = 6.dp), - text = restaurant.name, + text = restaurant.categoryDetail, color = Gray600, fontSize = 12.sp ) @@ -245,7 +244,7 @@ fun RestaurantImage(restaurant: RestaurantDataEntity) { modifier = Modifier .matchParentSize() .clip(RoundedCornerShape(8.dp)) - .background(Color.Black.copy(alpha = 0.5f)), + .background(Color.Black.copy(alpha = 0.2f)), contentAlignment = Alignment.Center ) { Text( diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt index 887363d7..862ae9fb 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt @@ -58,6 +58,14 @@ fun DetailSortCategoryType.title(): String { } } +fun DetailSortCategoryType.sort(): String { + return when (this) { + DetailSortCategoryType.POPULARITY -> "grade" + DetailSortCategoryType.DISTANCE -> "distance" + DetailSortCategoryType.RECENT -> "registDate" + } +} + enum class ReportCategoryType { IRRELAVANT, SLANG, 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 3d3513fd..23fdc16a 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 @@ -123,12 +123,15 @@ fun DetailListScreen( } ) { innerPadding -> LazyColumn( - modifier = Modifier - .padding(innerPadding) - .padding(horizontal = 20.dp), + modifier = Modifier.padding(innerPadding) ) { item { - Row { + Spacer(modifier = Modifier.padding(8.dp)) + Row( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 20.dp) + ) { DetailScreenChip( title = detailListViewState.detailSortCategoryType.title(), isCategory = true, @@ -152,6 +155,7 @@ fun DetailListScreen( } ) } + Spacer(modifier = Modifier.padding(8.dp)) } items(pagingRestaurantList.itemCount) { index -> @@ -160,6 +164,7 @@ fun DetailListScreen( EveryMealRestaurantItem( restaurant = it, ) + Spacer(modifier = Modifier.padding(16.dp)) } } } 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 b8909d58..ae6185d3 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 @@ -4,6 +4,7 @@ import androidx.lifecycle.viewModelScope import androidx.paging.PagingData import androidx.paging.cachedIn 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 @@ -13,12 +14,14 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class DetailListViewModel @Inject constructor( - private val getUnivRestaurantUseCase: GetUnivRestaurantUseCase + private val getUnivRestaurantUseCase: GetUnivRestaurantUseCase, + private val getUniversityIndexUseCase: GetUniversityIndexUseCase ): BaseViewModel( DetailState() ) { @@ -34,6 +37,7 @@ class DetailListViewModel @Inject constructor( reflectUpdateState( detailSortCategoryType = event.detailSortCategoryType ) + getRestaurantList() } is DetailEvent.SortBottomSheetStateChange -> { reflectUpdateState( @@ -75,11 +79,15 @@ class DetailListViewModel @Inject constructor( private fun getRestaurantList() { viewModelScope.launch { - getUnivRestaurantUseCase(1, "name", null, null) - .cachedIn(viewModelScope) - .collect { - _restaurantItems.emit(it) - } + getUnivRestaurantUseCase( + campusIdx = getUniversityIndexUseCase().first().toInt(), + order = viewState.value.detailSortCategoryType.sort(), + group = null, + grade = null + ).cachedIn(viewModelScope) + .collect { + _restaurantItems.emit(it) + } } } From f56255b2c5eb9a85f5c3d796b85a97b2c7c9d9e0 Mon Sep 17 00:00:00 2001 From: sgsk88 Date: Sat, 6 Jan 2024 18:24:52 +0900 Subject: [PATCH 07/11] =?UTF-8?q?[feature/get=5Frestaurant]=20=ED=95=84?= =?UTF-8?q?=ED=84=B0=20=EC=A0=81=EC=9A=A9=20=EA=B5=AC=ED=98=84=20(#88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/ui/detail/DetailListContract.kt | 10 ++++++++++ .../presentation/ui/detail/DetailListScreen.kt | 14 +++++++------- .../presentation/ui/detail/DetailListViewModel.kt | 5 +++-- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt index 862ae9fb..d29c79a7 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt @@ -117,4 +117,14 @@ fun RestaurantCategoryType.title(): String { RestaurantCategoryType.DRINK -> "술집" RestaurantCategoryType.NONE -> "" } +} + +fun RestaurantCategoryType.sort() : String { + return when (this) { + RestaurantCategoryType.RECOMMEND -> "recommend" + RestaurantCategoryType.RICE -> "restaurant" + RestaurantCategoryType.CAFE -> "cafe" + RestaurantCategoryType.DRINK -> "bar" + RestaurantCategoryType.NONE -> "all" + } } \ No newline at end of file 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 23fdc16a..55bc530f 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 @@ -147,13 +147,13 @@ fun DetailListScreen( detailListViewModel.setEvent(DetailContract.DetailEvent.MealRatingBottomSheetStateChange(true)) } ) - DetailScreenChip( - title = "TEST신고버튼", - isCategory = true, - onChipClicked = { - detailListViewModel.setEvent(DetailContract.DetailEvent.ReportBottomSheetStateChange(true)) - } - ) +// DetailScreenChip( +// title = "TEST신고버튼", +// isCategory = true, +// onChipClicked = { +// detailListViewModel.setEvent(DetailContract.DetailEvent.ReportBottomSheetStateChange(true)) +// } +// ) } Spacer(modifier = Modifier.padding(8.dp)) } 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 ae6185d3..b94b768a 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 @@ -48,6 +48,7 @@ class DetailListViewModel @Inject constructor( reflectUpdateState( mealRatingBottomSheetState = event.mealRatingBottomSheetState ) + getRestaurantList() } is DetailEvent.ReportBottomSheetStateChange -> { reflectUpdateState( @@ -82,8 +83,8 @@ class DetailListViewModel @Inject constructor( getUnivRestaurantUseCase( campusIdx = getUniversityIndexUseCase().first().toInt(), order = viewState.value.detailSortCategoryType.sort(), - group = null, - grade = null + group = viewState.value.restaurantCategoryType.sort(), + grade = if(viewState.value.rating == 0) null else viewState.value.rating.toString() ).cachedIn(viewModelScope) .collect { _restaurantItems.emit(it) From 2188c2295748c3af5235f65c63fddeb1ddf82111 Mon Sep 17 00:00:00 2001 From: sgsk88 Date: Sat, 6 Jan 2024 19:04:20 +0900 Subject: [PATCH 08/11] =?UTF-8?q?[feature/get=5Frestaurant]=20=ED=95=84?= =?UTF-8?q?=ED=84=B0=20=EC=A1=B0=EA=B1=B4=20=EC=BB=AC=EB=9F=AC=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=20(#88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/detail/DetailListScreen.kt | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) 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 55bc530f..faae92d2 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 @@ -23,8 +23,10 @@ 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 +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel @@ -40,6 +42,8 @@ import com.everymeal.presentation.components.EveryMealSortCategoryBottomSheetDia import com.everymeal.presentation.ui.save.SaveTopBar 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 @@ -145,7 +149,8 @@ fun DetailListScreen( isCategory = true, onChipClicked = { detailListViewModel.setEvent(DetailContract.DetailEvent.MealRatingBottomSheetStateChange(true)) - } + }, + detailListViewState = detailListViewState ) // DetailScreenChip( // title = "TEST신고버튼", @@ -176,13 +181,22 @@ fun DetailScreenChip( title: String, isCategory: Boolean, onChipClicked: () -> Unit, + detailListViewState: DetailContract.DetailState? = null ) { + val isRatingOrCategory = detailListViewState?.let { + it.rating != 0 || it.restaurantCategoryType.name != "NONE" + } ?: false + Surface( modifier = Modifier.clickable( indication = null, interactionSource = remember { MutableInteractionSource() } ) { onChipClicked() }, - color = Grey2, + color = when { + detailListViewState == null -> Grey2 + isRatingOrCategory -> SubMain100 + else -> Grey2 + }, shape = RoundedCornerShape(100.dp), ) { Row( @@ -190,9 +204,14 @@ fun DetailScreenChip( ) { Text( text = title, - color = Grey7, + color = when { + detailListViewState == null -> Grey7 + isRatingOrCategory -> Main100 + else -> Grey7 + }, style = Typography.bodySmall, - modifier = Modifier.padding(start = 12.dp, end = 4.dp, top = 6.dp, bottom = 6.dp) + modifier = Modifier.padding(start = 12.dp, end = 4.dp, top = 6.dp, bottom = 6.dp), + fontWeight = FontWeight.Bold ) if(isCategory) { Image( @@ -200,7 +219,12 @@ fun DetailScreenChip( .padding(end = 12.dp) .size(12.dp), imageVector = ImageVector.vectorResource(id = R.drawable.icon_arrow_bottom), - contentDescription = "arrow_bottom" + contentDescription = "arrow_bottom", + colorFilter = when { + detailListViewState == null -> ColorFilter.tint(Grey7) + isRatingOrCategory -> ColorFilter.tint(Main100) + else -> ColorFilter.tint(Grey7) + } ) } else { Image( From 8e639302fe939f4cb9f8911c23941b0e824c8871 Mon Sep 17 00:00:00 2001 From: sgsk88 Date: Sat, 6 Jan 2024 19:17:49 +0900 Subject: [PATCH 09/11] =?UTF-8?q?[feature/get=5Frestaurant]=20=ED=95=84?= =?UTF-8?q?=ED=84=B0=20=EC=B9=B4=ED=85=8C=EA=B3=A0=EB=A6=AC=20=EC=B9=A9=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/ui/detail/DetailListContract.kt | 1 + .../presentation/ui/detail/DetailListScreen.kt | 11 +++++++++++ .../presentation/ui/detail/DetailListViewModel.kt | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt index d29c79a7..d96050ca 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt @@ -28,6 +28,7 @@ class DetailContract { data class OnClickReportCategoryType(val reportCategoryType: ReportCategoryType) : DetailEvent() data class OnClickRestaurantCategoryType(val restaurantCategoryType: RestaurantCategoryType) : DetailEvent() data class OnClickRating(val rating: Int) : DetailEvent() + object OnDeleteClickRestaurantCategoryType : DetailEvent() } sealed class DetailEffect : ViewSideEffect { 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 faae92d2..b196cedd 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 @@ -152,6 +152,17 @@ fun DetailListScreen( }, detailListViewState = detailListViewState ) + if(detailListViewState.restaurantCategoryType.title().isNotEmpty()) { + Spacer(modifier = Modifier.padding(4.dp)) + DetailScreenChip( + title = detailListViewState.restaurantCategoryType.title(), + isCategory = false, + onChipClicked = { + detailListViewModel.setEvent(DetailContract.DetailEvent.OnDeleteClickRestaurantCategoryType) + }, + detailListViewState = detailListViewState + ) + } // DetailScreenChip( // title = "TEST신고버튼", // isCategory = true, 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 b94b768a..2ef342e8 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 @@ -75,6 +75,12 @@ class DetailListViewModel @Inject constructor( restaurantCategoryType = event.restaurantCategoryType ) } + is DetailEvent.OnDeleteClickRestaurantCategoryType -> { + reflectUpdateState( + restaurantCategoryType = RestaurantCategoryType.NONE + ) + getRestaurantList() + } } } From 570ae281f3dbe178a937ebbd2bc8556e4e74eeaa Mon Sep 17 00:00:00 2001 From: sgsk88 Date: Sat, 6 Jan 2024 19:37:52 +0900 Subject: [PATCH 10/11] =?UTF-8?q?[feature/get=5Frestaurant]=20=EB=B3=84?= =?UTF-8?q?=EC=A0=90=20=EC=B9=A9=20=ED=99=9C=EC=84=B1=ED=99=94=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20(#88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/detail/DetailListContract.kt | 1 + .../ui/detail/DetailListScreen.kt | 34 +++++++++++++++---- .../ui/detail/DetailListViewModel.kt | 6 ++++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt index d96050ca..34ae6b26 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/detail/DetailListContract.kt @@ -29,6 +29,7 @@ class DetailContract { data class OnClickRestaurantCategoryType(val restaurantCategoryType: RestaurantCategoryType) : DetailEvent() data class OnClickRating(val rating: Int) : DetailEvent() object OnDeleteClickRestaurantCategoryType : DetailEvent() + object OnDeleteClickRating : DetailEvent() } sealed class DetailEffect : ViewSideEffect { 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 b196cedd..6c516a5f 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 @@ -29,6 +29,7 @@ import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.paging.compose.LazyPagingItems import androidx.paging.compose.collectAsLazyPagingItems @@ -138,7 +139,6 @@ fun DetailListScreen( ) { DetailScreenChip( title = detailListViewState.detailSortCategoryType.title(), - isCategory = true, onChipClicked = { detailListViewModel.setEvent(DetailContract.DetailEvent.SortBottomSheetStateChange(true)) } @@ -146,7 +146,6 @@ fun DetailListScreen( Spacer(modifier = Modifier.padding(4.dp)) DetailScreenChip( title = "필터", - isCategory = true, onChipClicked = { detailListViewModel.setEvent(DetailContract.DetailEvent.MealRatingBottomSheetStateChange(true)) }, @@ -163,6 +162,18 @@ fun DetailListScreen( detailListViewState = detailListViewState ) } + if(detailListViewState.rating != 0) { + Spacer(modifier = Modifier.padding(4.dp)) + DetailScreenChip( + title = "${detailListViewState.rating}", + isCategory = false, + isRating = true, + onChipClicked = { + detailListViewModel.setEvent(DetailContract.DetailEvent.OnDeleteClickRating) + }, + detailListViewState = detailListViewState + ) + } // DetailScreenChip( // title = "TEST신고버튼", // isCategory = true, @@ -190,7 +201,8 @@ fun DetailListScreen( @Composable fun DetailScreenChip( title: String, - isCategory: Boolean, + isCategory: Boolean = true, + isRating: Boolean = false, onChipClicked: () -> Unit, detailListViewState: DetailContract.DetailState? = null ) { @@ -213,6 +225,16 @@ fun DetailScreenChip( Row( verticalAlignment = Alignment.CenterVertically ) { + 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) + ) + } Text( text = title, color = when { @@ -220,9 +242,9 @@ fun DetailScreenChip( isRatingOrCategory -> Main100 else -> Grey7 }, - style = Typography.bodySmall, - modifier = Modifier.padding(start = 12.dp, end = 4.dp, top = 6.dp, bottom = 6.dp), - fontWeight = FontWeight.Bold + 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 ) if(isCategory) { Image( 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 2ef342e8..efd423fe 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 @@ -81,6 +81,12 @@ class DetailListViewModel @Inject constructor( ) getRestaurantList() } + is DetailEvent.OnDeleteClickRating -> { + reflectUpdateState( + rating = 0 + ) + getRestaurantList() + } } } From cc2d2884510732349087a201ec9345e4b41c76ba Mon Sep 17 00:00:00 2001 From: sgsk88 Date: Sat, 20 Jan 2024 21:28:01 +0900 Subject: [PATCH 11/11] =?UTF-8?q?[feature/get=5Frestaurant]=20api=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EB=B9=88=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(#88)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/service/restaurant/RestaurantApi.kt | 2 +- .../ui/univfood/UnivFoodScreen.kt | 45 +++++++++++++++++-- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/data/src/main/java/com/everymeal/data/service/restaurant/RestaurantApi.kt b/data/src/main/java/com/everymeal/data/service/restaurant/RestaurantApi.kt index 5ea42b0d..f961741f 100644 --- a/data/src/main/java/com/everymeal/data/service/restaurant/RestaurantApi.kt +++ b/data/src/main/java/com/everymeal/data/service/restaurant/RestaurantApi.kt @@ -8,7 +8,7 @@ import retrofit2.http.Query interface RestaurantApi { - @GET("/api/v1/stores/{campusIdx}") + @GET("/api/v1/stores/campus/{campusIdx}") suspend fun getUnivRestaurant( @Path("campusIdx") campusIdx: Int, @Query("offset") offset: Int, diff --git a/presentation/src/main/java/com/everymeal/presentation/ui/univfood/UnivFoodScreen.kt b/presentation/src/main/java/com/everymeal/presentation/ui/univfood/UnivFoodScreen.kt index 5b69b4d9..23e21fff 100644 --- a/presentation/src/main/java/com/everymeal/presentation/ui/univfood/UnivFoodScreen.kt +++ b/presentation/src/main/java/com/everymeal/presentation/ui/univfood/UnivFoodScreen.kt @@ -1,16 +1,55 @@ package com.everymeal.presentation.ui.univfood +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.size import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.everymeal.presentation.R +import com.everymeal.presentation.ui.theme.EveryMealTypo +import com.everymeal.presentation.ui.theme.Gray700 @Composable fun UnivFoodScreen( ) { - Text( - text = "UnivFoodScreen", - ) + Column( + modifier = Modifier.fillMaxSize(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Image( + modifier = Modifier.size(200.dp), + painter = painterResource(id = R.drawable.icon_what_food_main), + contentDescription = "WhatFoodMain" + ) + Spacer(modifier = Modifier.size(10.dp)) + Text( + text = stringResource(id = R.string.what_food_current_service), + style = EveryMealTypo.titleMedium, + color = Color.Black + ) + Spacer(modifier = Modifier.size(10.dp)) + Text( + text = stringResource(id = R.string.what_food_everymeal_ready), + style = EveryMealTypo.bodySmall, + color = Gray700, + fontSize = 14.sp, + textAlign = TextAlign.Center + ) + } } @Preview