Skip to content

Commit

Permalink
feat: 투표 추가 서버 연동
Browse files Browse the repository at this point in the history
  • Loading branch information
jinukeu committed Jan 24, 2024
1 parent fc69408 commit 0655e26
Show file tree
Hide file tree
Showing 11 changed files with 181 additions and 5 deletions.
9 changes: 9 additions & 0 deletions core/model/src/main/java/com/susu/core/model/Vote.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.susu.core.model

data class Vote(
val id: Long,
val category: String,
val content: String,
val isModified: Boolean,
val optionList: List<String>
)
7 changes: 7 additions & 0 deletions data/src/main/java/com/susu/data/data/di/RepositoryModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.susu.data.data.repository.SignUpRepositoryImpl
import com.susu.data.data.repository.TermRepositoryImpl
import com.susu.data.data.repository.TokenRepositoryImpl
import com.susu.data.data.repository.UserRepositoryImpl
import com.susu.data.data.repository.VoteRepositoryImpl
import com.susu.domain.repository.CategoryConfigRepository
import com.susu.domain.repository.ExcelRepository
import com.susu.domain.repository.LedgerRecentSearchRepository
Expand All @@ -18,6 +19,7 @@ import com.susu.domain.repository.SignUpRepository
import com.susu.domain.repository.TermRepository
import com.susu.domain.repository.TokenRepository
import com.susu.domain.repository.UserRepository
import com.susu.domain.repository.VoteRepository
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
Expand Down Expand Up @@ -71,4 +73,9 @@ abstract class RepositoryModule {
abstract fun bindExcelRepository(
excelRepositoryImpl: ExcelRepositoryImpl,
): ExcelRepository

@Binds
abstract fun bindVoteRepository(
voteRepositoryImpl: VoteRepositoryImpl,
): VoteRepository
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.susu.data.data.repository

import com.susu.core.android.Dispatcher
import com.susu.core.android.SusuDispatchers
import com.susu.core.model.Category
import com.susu.core.model.Vote
import com.susu.data.local.dao.CategoryConfigDao
import com.susu.data.local.model.toEntity
import com.susu.data.local.model.toModel
import com.susu.data.remote.api.CategoryService
import com.susu.data.remote.api.VoteService
import com.susu.data.remote.model.request.CreateVoteRequest
import com.susu.data.remote.model.request.VoteOption
import com.susu.data.remote.model.response.toModel
import com.susu.domain.repository.CategoryConfigRepository
import com.susu.domain.repository.VoteRepository
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext
import javax.inject.Inject

class VoteRepositoryImpl @Inject constructor(
private val api: VoteService,
) : VoteRepository {
override suspend fun createVote(
content: String,
optionList: List<String>,
categoryId: Int,
): Vote = api.createVote(
createVoteRequest = CreateVoteRequest(
content = content,
optionList = optionList.mapIndexed { index, voteContent ->
VoteOption(
content = voteContent,
seq = index + 1,
)
},
categoryId = categoryId,
),
).getOrThrow().toModel()
}
15 changes: 15 additions & 0 deletions data/src/main/java/com/susu/data/remote/api/VoteService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.susu.data.remote.api

import com.susu.data.remote.model.request.CreateVoteRequest
import com.susu.data.remote.model.response.VoteResponse
import com.susu.data.remote.retrofit.ApiResult
import retrofit2.http.Body
import retrofit2.http.POST

interface VoteService {

@POST("/api/v1/votes")
suspend fun createVote(
@Body createVoteRequest: CreateVoteRequest
): ApiResult<VoteResponse>
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.susu.data.remote.api.SignUpService
import com.susu.data.remote.api.TermService
import com.susu.data.remote.api.TokenService
import com.susu.data.remote.api.UserService
import com.susu.data.remote.api.VoteService
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand Down Expand Up @@ -59,4 +60,10 @@ object ApiServiceModule {
fun providesUserService(retrofit: Retrofit): UserService {
return retrofit.create(UserService::class.java)
}

@Singleton
@Provides
fun providesVoteService(retrofit: Retrofit): VoteService {
return retrofit.create(VoteService::class.java)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.susu.data.remote.model.request

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class CreateVoteRequest(
val content: String,
@SerialName("options")
val optionList: List<VoteOption>,
@SerialName("postCategoryId")
val categoryId: Int
)

@Serializable
data class VoteOption(
val content: String,
val seq: Int
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.susu.data.remote.model.response

import com.susu.core.model.Vote
import com.susu.data.remote.model.request.VoteOption
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class VoteResponse(
val id: Long,
val category: String,
val content: String,
val isModified: Boolean,
@SerialName("options")
val optionList: List<VoteOption>
)

internal fun VoteResponse.toModel() = Vote(
id = id,
category = category,
content = content,
isModified = isModified,
optionList = optionList.sortedBy { it.seq }.map { it.content },
)
11 changes: 11 additions & 0 deletions domain/src/main/java/com/susu/domain/repository/VoteRepository.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.susu.domain.repository

import com.susu.core.model.Vote

interface VoteRepository {
suspend fun createVote(
content: String,
optionList: List<String>,
categoryId: Int
): Vote
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.susu.domain.usecase.vote

import com.susu.core.common.runCatchingIgnoreCancelled
import com.susu.domain.repository.CategoryConfigRepository
import com.susu.domain.repository.VoteRepository
import javax.inject.Inject

class CreateVoteUseCase @Inject constructor(
private val voteRepository: VoteRepository,
) {
suspend operator fun invoke(param: Param) = runCatchingIgnoreCancelled {
with(param) {
voteRepository.createVote(
content = content,
optionList = optionList,
categoryId = categoryId,
)
}
}

data class Param(
val content: String,
val optionList: List<String>,
val categoryId: Int,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ fun VoteAddRoute(
VoteAddScreen(
uiState = uiState,
onClickBack = viewModel::popBackStack,
onClickRegister = {},
onClickRegister = viewModel::createVote,
onClickCategoryButton = viewModel::selectCategory,
onTextChangeContent = viewModel::updateContent,
onTextChangeOptionContent = viewModel::updateOptionContent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ import androidx.lifecycle.viewModelScope
import com.susu.core.model.Category
import com.susu.core.ui.base.BaseViewModel
import com.susu.domain.usecase.categoryconfig.GetCategoryConfigUseCase
import com.susu.domain.usecase.vote.CreateVoteUseCase
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject

@HiltViewModel
class VoteAddViewModel @Inject constructor(
private val getCategoryConfigUseCase: GetCategoryConfigUseCase,
private val createVoteUseCase: CreateVoteUseCase,
) : BaseViewModel<VoteAddState, VoteAddSideEffect>(
VoteAddState(),
) {
Expand All @@ -20,6 +23,21 @@ class VoteAddViewModel @Inject constructor(
private const val MAX_OPTION_COUNT = 5
}

fun createVote() = viewModelScope.launch {
createVoteUseCase(
param = CreateVoteUseCase.Param(
content = currentState.content,
optionList = currentState.voteOptionStateList.map { it.content },
categoryId = currentState.selectedCategory.id,
),
).onSuccess {
Timber.tag("테스트").d("$it")
popBackStack()
}.onFailure {
postSideEffect(VoteAddSideEffect.HandleException(it, ::createVote))
}
}

fun getCategoryConfig() = viewModelScope.launch {
if (currentState.categoryConfigList.isNotEmpty()) return@launch

Expand Down Expand Up @@ -48,7 +66,7 @@ class VoteAddViewModel @Inject constructor(
voteOptionStateList = voteOptionStateList.mapIndexed { voteIndex, voteOptionState ->
if (index == voteIndex) voteOptionState.copy(content = content)
else voteOptionState
}.toPersistentList()
}.toPersistentList(),
)
}

Expand All @@ -57,21 +75,21 @@ class VoteAddViewModel @Inject constructor(
voteOptionStateList = voteOptionStateList.mapIndexed { voteIndex, voteOptionState ->
if (index == voteIndex) voteOptionState.copy(isSaved = voteOptionState.isSaved.not())
else voteOptionState
}.toPersistentList()
}.toPersistentList(),
)
}

fun removeOptionState(index: Int) = intent {
if (voteOptionStateList.size <= MIN_OPTION_COUNT) return@intent this
copy(
voteOptionStateList = voteOptionStateList.removeAt(index)
voteOptionStateList = voteOptionStateList.removeAt(index),
)
}

fun addOptionState() = intent {
if (voteOptionStateList.size >= MAX_OPTION_COUNT) return@intent this
copy(
voteOptionStateList = voteOptionStateList.add(VoteOptionState())
voteOptionStateList = voteOptionStateList.add(VoteOptionState()),
)
}
}

0 comments on commit 0655e26

Please sign in to comment.