Skip to content
This repository has been archived by the owner on Mar 8, 2024. It is now read-only.

Commit

Permalink
🔀 :: (#116) 추천 목록 조회 기능 구현
Browse files Browse the repository at this point in the history
🔀 :: (#116) 추천 목록 조회 기능 구현
  • Loading branch information
Tmdhoon2 authored Nov 23, 2023
2 parents 810aca2 + 8472fdb commit 0a44e75
Show file tree
Hide file tree
Showing 18 changed files with 211 additions and 42 deletions.
4 changes: 4 additions & 0 deletions data/src/main/kotlin/com/signal/data/api/ApiProvider.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ object ApiProvider {
return getRetrofit(tokenInterceptor).create(DiaryApi::class.java)
}

fun getRecommendApi(tokenInterceptor: TokenInterceptor): RecommendApi {
return getRetrofit(tokenInterceptor).create(RecommendApi::class.java)
}

fun getReservationApi(tokenInterceptor: TokenInterceptor): ReservationApi {
return getRetrofit(tokenInterceptor).create(ReservationApi::class.java)
}
Expand Down
13 changes: 13 additions & 0 deletions data/src/main/kotlin/com/signal/data/api/RecommendApi.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.signal.data.api

import com.signal.data.model.recommend.FetchRecommendsResponse
import com.signal.domain.enums.Category
import retrofit2.http.GET
import retrofit2.http.Query

interface RecommendApi {
@GET(SignalUrl.Recommend.FetchRecommends)
suspend fun fetchRecommends(
@Query("category") category: Category,
): FetchRecommendsResponse
}
5 changes: 5 additions & 0 deletions data/src/main/kotlin/com/signal/data/api/SignalUrl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ object SignalUrl {
private const val feed = "/feed"
private const val attachment = "/attachment"
private const val diary = "/diary"
private const val recommend = "/recommend"
private const val reservation = "/reservation"
private const val admin = "/admin"

Expand Down Expand Up @@ -36,6 +37,10 @@ object SignalUrl {
const val DeleteDiary = "$diary/{diary_id}"
}

object Recommend{
const val FetchRecommends = "$recommend/list"
}

object Reservation {
const val FetchHospitals = "$admin/hospital/list"
const val FetchDayReservation = "$reservation/user"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.signal.data.datasource.recommend

import com.signal.data.model.recommend.FetchRecommendsResponse
import com.signal.domain.enums.Category

interface RecommendDataSource {
suspend fun fetchRecommends(category: Category): FetchRecommendsResponse
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.signal.data.datasource.recommend

import com.signal.data.api.RecommendApi
import com.signal.data.model.recommend.FetchRecommendsResponse
import com.signal.data.util.ExceptionHandler
import com.signal.domain.enums.Category

class RecommendDataSourceImpl(
private val recommendApi: RecommendApi,
) : RecommendDataSource {
override suspend fun fetchRecommends(category: Category) =
ExceptionHandler<FetchRecommendsResponse>().httpRequest {
recommendApi.fetchRecommends(category = category)
}.sendRequest()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.signal.data.model.recommend

import com.google.gson.annotations.SerializedName
import com.signal.domain.entity.RecommendsEntity
import java.util.UUID

data class FetchRecommendsResponse(
@SerializedName("recommend_list") val recommends: List<Recommend>,
) {
data class Recommend(
@SerializedName("id") val id: UUID,
@SerializedName("title") val title: String,
@SerializedName("content") val content: String,
@SerializedName("image") val image: String,
)
}

fun FetchRecommendsResponse.toEntity() = RecommendsEntity(
recommends = this.recommends.map { it.toEntity() },
)

fun FetchRecommendsResponse.Recommend.toEntity() = RecommendsEntity.Recommend(
id = this.id,
title = this.title,
content = this.content,
image = this.image,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.signal.data.repository

import com.signal.data.datasource.recommend.RecommendDataSource
import com.signal.data.model.recommend.toEntity
import com.signal.domain.enums.Category
import com.signal.domain.repository.RecommendRepository

class RecommendRepositoryImpl(
private val recommendDataSource: RecommendDataSource,
) : RecommendRepository {
override suspend fun fetchRecommends(category: Category) = kotlin.runCatching {
recommendDataSource.fetchRecommends(category = category).toEntity()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.signal.domain.entity

import java.util.UUID

data class RecommendsEntity(
val recommends: List<Recommend>,
) {
data class Recommend(
val id: UUID,
val title: String,
val content: String,
val image: String,
)
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.signal.domain.enums

enum class RecommendType {
enum class Category {
MUSIC,
EXERCISE,
SPORT,
VIDEO,
HOSPITAL,
HOBBY,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.signal.domain.repository

import com.signal.domain.entity.RecommendsEntity
import com.signal.domain.enums.Category

interface RecommendRepository {
suspend fun fetchRecommends(category: Category): Result<RecommendsEntity>
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import com.signal.data.datasource.feed.FeedDataSource
import com.signal.data.datasource.feed.FeedDataSourceImpl
import com.signal.data.datasource.file.AttachmentDataSource
import com.signal.data.datasource.file.AttachmentDataSourceImpl
import com.signal.data.datasource.recommend.RecommendDataSource
import com.signal.data.datasource.recommend.RecommendDataSourceImpl
import com.signal.data.datasource.reservation.ReservationDataSource
import com.signal.data.datasource.reservation.ReservationDataSourceImpl
import com.signal.data.datasource.user.local.LocalUserDataSource
Expand All @@ -22,6 +24,7 @@ import com.signal.data.repository.AttachmentRepositoryImpl
import com.signal.data.repository.DiagnosisRepositoryImpl
import com.signal.data.repository.DiaryRepositoryImpl
import com.signal.data.repository.FeedRepositoryImpl
import com.signal.data.repository.RecommendRepositoryImpl
import com.signal.data.repository.ReservationRepositoryImpl
import com.signal.data.repository.UserRepositoryImpl
import com.signal.data.util.PreferenceManager
Expand All @@ -30,6 +33,7 @@ import com.signal.domain.repository.AttachmentRepository
import com.signal.domain.repository.DiagnosisRepository
import com.signal.domain.repository.DiaryRepository
import com.signal.domain.repository.FeedRepository
import com.signal.domain.repository.RecommendRepository
import com.signal.domain.repository.ReservationRepository
import com.signal.domain.repository.UserRepository
import com.signal.domain.usecase.users.AddFamousSayingUseCase
Expand All @@ -47,6 +51,7 @@ import com.signal.signal_android.feature.file.AttachmentViewModel
import com.signal.signal_android.feature.main.diary.DiaryViewModel
import com.signal.signal_android.feature.main.feed.FeedViewModel
import com.signal.signal_android.feature.main.home.HomeViewModel
import com.signal.signal_android.feature.main.recommend.RecommendViewModel
import com.signal.signal_android.feature.mypage.MyPageViewModel
import com.signal.signal_android.feature.reservation.ReservationViewModel
import com.signal.signal_android.feature.signin.SignInViewModel
Expand Down Expand Up @@ -87,6 +92,7 @@ val apiModule: Module
single { ApiProvider.getFeedApi(tokenInterceptor = get()) }
single { ApiProvider.getFileApi(tokenInterceptor = get()) }
single { ApiProvider.getDiaryApi(tokenInterceptor = get()) }
single { ApiProvider.getRecommendApi(tokenInterceptor = get()) }
single { ApiProvider.getReservationApi(tokenInterceptor = get()) }
}

Expand All @@ -109,7 +115,6 @@ val daoModule: Module
}
single {
PreferenceManager(context = androidContext())

}
}

Expand All @@ -131,6 +136,7 @@ val dataSourceModule: Module
)
}
single<DiaryDataSource> { DiaryDataSourceImpl(diaryApi = get()) }
single<RecommendDataSource> { RecommendDataSourceImpl(recommendApi = get()) }
single<ReservationDataSource> { ReservationDataSourceImpl(reservationApi = get()) }
}

Expand All @@ -154,6 +160,9 @@ val repositoryModule: Module
single<DiaryRepository> {
DiaryRepositoryImpl(diaryDateSource = get())
}
single<RecommendRepository> {
RecommendRepositoryImpl(recommendDataSource = get())
}
single<ReservationRepository> {
ReservationRepositoryImpl(reservationDataSource = get())
}
Expand Down Expand Up @@ -206,5 +215,6 @@ val viewModelModule: Module
)
}
viewModel { DiaryViewModel(diaryRepository = get()) }
viewModel { RecommendViewModel(recommendRepository = get()) }
viewModel { ReservationViewModel(reservationRepository = get()) }
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.signal.domain.enums.RecommendType
import com.signal.domain.enums.Category
import com.signal.signal_android.R
import com.signal.signal_android.designsystem.component.Indicator
import com.signal.signal_android.designsystem.foundation.Body2
Expand Down Expand Up @@ -100,7 +100,7 @@ private fun ColumnScope.Categories(
.signalClickable(
rippleEnabled = true,
onClick = {
moveToRecommends(RecommendType.values()[index].toString())
moveToRecommends(Category.values()[index].toString())
},
),
horizontalAlignment = Alignment.CenterHorizontally,
Expand Down Expand Up @@ -188,7 +188,7 @@ private fun ColumnScope.Trends(
.signalClickable(
rippleEnabled = true,
onClick = {
moveToRecommends(RecommendType.values()[pagerState.currentPage].toString())
moveToRecommends(Category.values()[pagerState.currentPage].toString())
},
)
.fillMaxHeight(0.25f),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.signal.signal_android.feature.main.recommend

interface RecommendSideEffect {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.signal.signal_android.feature.main.recommend

import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.snapshots.SnapshotStateList
import com.signal.domain.entity.RecommendsEntity
import com.signal.domain.enums.Category

data class RecommendState(
val recommends: SnapshotStateList<RecommendsEntity.Recommend>,
val category: Category,
) {
companion object {
fun getDefaultState() = RecommendState(
recommends = mutableStateListOf(),
category = Category.MUSIC,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.signal.signal_android.feature.main.recommend

import androidx.compose.runtime.toMutableStateList
import androidx.lifecycle.viewModelScope
import com.signal.domain.enums.Category
import com.signal.domain.repository.RecommendRepository
import com.signal.signal_android.BaseViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class RecommendViewModel(
private val recommendRepository: RecommendRepository,
) : BaseViewModel<RecommendState, RecommendSideEffect>(RecommendState.getDefaultState()) {
internal fun fetchRecommends() {
with(state.value) {
viewModelScope.launch(Dispatchers.IO) {
recommendRepository.fetchRecommends(category = category).onSuccess {
setState(copy(recommends = it.recommends.toMutableStateList()))
}
}
}
}

internal fun setCategory(category: Category) {
setState(state.value.copy(category = category))
}
}
Loading

0 comments on commit 0a44e75

Please sign in to comment.