Skip to content

Commit

Permalink
Merge pull request #101 from YAPP-Github/feature/MZ-203-vote-list-api
Browse files Browse the repository at this point in the history
Feature/mz 203 vote list api
  • Loading branch information
jinukeu authored Jan 27, 2024
2 parents 35c53ac + 7816dea commit 02486b1
Show file tree
Hide file tree
Showing 29 changed files with 547 additions and 60 deletions.
23 changes: 20 additions & 3 deletions core/model/src/main/java/com/susu/core/model/Vote.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
package com.susu.core.model

import androidx.compose.runtime.Stable
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.toKotlinLocalDateTime
import kotlinx.serialization.Serializable

@Stable
@Serializable
data class Vote(
val id: Long = 0,
val uid: Long = 0,
val category: String = "",
val content: String = "",
val count: Int = 0,
val isModified: Boolean = false,
val createdAt: LocalDateTime = java.time.LocalDateTime.now().toKotlinLocalDateTime(),
val optionList: List<VoteOption> = emptyList(),
)

@Stable
@Serializable
data class VoteOption(
val id: Long,
val category: String,
val content: String,
val isModified: Boolean,
val optionList: List<String>,
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import androidx.compose.runtime.snapshotFlow
fun LazyListState.OnBottomReached(
// tells how many items before we reach the bottom of the list
// to call onLoadMore function
buffer: Int = 3,
buffer: Int = 0,
minItemsCount: Int = 0,
onLoadMore: () -> Unit,
) {
// Buffer must be positive.
Expand All @@ -22,6 +23,7 @@ fun LazyListState.OnBottomReached(
val shouldLoadMore = remember {
derivedStateOf {
val lastVisibleItem = layoutInfo.visibleItemsInfo.lastOrNull() ?: return@derivedStateOf false
if (lastVisibleItem.index < minItemsCount) return@derivedStateOf false

lastVisibleItem.index >= layoutInfo.totalItemsCount - 1 - buffer
}
Expand Down
4 changes: 4 additions & 0 deletions core/ui/src/main/java/com/susu/core/ui/util/Date.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ fun getSafeLocalDateTime(year: Int, month: Int, day: Int): LocalDateTime = try {
Log.e("DateTimeError", "Invalid date provided: $year-$month-$day", e)
LocalDateTime.of(year, month, 1, 0, 0)
}

fun isBetween(target: LocalDateTime, start: LocalDateTime, end: LocalDateTime): Boolean {
return !target.isBefore(start) && !target.isAfter(end)
}
1 change: 1 addition & 0 deletions core/ui/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,5 @@
<string name="word_register">등록</string>
<string name="word_free">자유</string>
<string name="content_description_report_button">신고 버튼</string>
<string name="word_all">전체</string>
</resources>
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.susu.data.data.repository

import com.susu.core.model.Category
import com.susu.core.model.Vote
import com.susu.data.local.model.toModel
import com.susu.data.remote.api.VoteService
Expand Down Expand Up @@ -28,4 +29,26 @@ class VoteRepositoryImpl @Inject constructor(
categoryId = categoryId,
),
).getOrThrow().toModel()

override suspend fun getVoteList(
content: String?,
mine: Boolean?,
sortType: String?,
categoryId: Int?,
page: Int?,
size: Int?,
sort: String?,
): List<Vote> = api.getVoteList(
content = content,
mine = mine,
sortType = sortType,
categoryId = categoryId,
page = page,
size = size,
sort = sort,
).getOrThrow().toModel()

override suspend fun getPopularVoteList(): List<Vote> = api.getPopularVoteList().getOrThrow().map { it.toModel() }

override suspend fun getPostCategoryConfig(): List<Category> = api.getPostCategoryConfig().getOrThrow().map { it.toModel() }
}
24 changes: 23 additions & 1 deletion data/src/main/java/com/susu/data/remote/api/VoteService.kt
Original file line number Diff line number Diff line change
@@ -1,15 +1,37 @@
package com.susu.data.remote.api

import com.susu.data.remote.model.request.CreateVoteRequest
import com.susu.data.remote.model.response.PopularVoteResponse
import com.susu.data.remote.model.response.PostCategoryConfig
import com.susu.data.remote.model.response.VoteListResponse
import com.susu.data.remote.model.response.VoteResponse
import com.susu.data.remote.retrofit.ApiResult
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Query

interface VoteService {

@POST("/api/v1/votes")
@POST("votes")
suspend fun createVote(
@Body createVoteRequest: CreateVoteRequest,
): ApiResult<VoteResponse>

@GET("votes")
suspend fun getVoteList(
@Query("content") content: String?,
@Query("mine") mine: Boolean?,
@Query("sortType") sortType: String?,
@Query("categoryId") categoryId: Int?,
@Query("page") page: Int?,
@Query("size") size: Int?,
@Query("sort") sort: String?,
): ApiResult<VoteListResponse>

@GET("votes/popular")
suspend fun getPopularVoteList(): ApiResult<List<PopularVoteResponse>>

@GET("posts/configs/create-post")
suspend fun getPostCategoryConfig(): ApiResult<List<PostCategoryConfig>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ data class CreateVoteRequest(

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

import com.susu.core.model.Vote
import kotlinx.datetime.toKotlinLocalDateTime
import kotlinx.serialization.Serializable
import java.time.LocalDateTime

@Serializable
data class PopularVoteResponse(
val id: Long,
val category: String,
val content: String,
val count: Int,
val isModified: Boolean,
)

internal fun PopularVoteResponse.toModel() = Vote(
id = id,
uid = 0,
category = category,
content = content,
isModified = isModified,
count = count,
createdAt = LocalDateTime.now().toKotlinLocalDateTime(),
optionList = listOf(),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.susu.data.remote.model.response

import com.susu.core.model.Category
import kotlinx.serialization.Serializable

@Serializable
data class PostCategoryConfig(
val id: Int,
val name: String,
)

internal fun PostCategoryConfig.toModel() = Category(
id = id,
name = name,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.susu.data.remote.model.response

import kotlinx.serialization.Serializable

@Serializable
data class VoteListResponse(
val data: List<VoteResponse> = emptyList(),
)

internal fun VoteListResponse.toModel() = data.map { it.toModel() }
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,34 @@ package com.susu.data.remote.model.response

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

@Serializable
data class VoteResponse(
val id: Long,
val uid: Long = 0,
val category: String,
val content: String,
val isModified: Boolean,
val createdAt: LocalDateTime = java.time.LocalDateTime.now().toKotlinLocalDateTime(),
@SerialName("options")
val optionList: List<VoteOption>,
)

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

import com.susu.core.model.Category
import com.susu.core.model.Vote

interface VoteRepository {
Expand All @@ -8,4 +9,18 @@ interface VoteRepository {
optionList: List<String>,
categoryId: Int,
): Vote

suspend fun getVoteList(
content: String?,
mine: Boolean?,
sortType: String?,
categoryId: Int?,
page: Int?,
size: Int?,
sort: String?,
): List<Vote>

suspend fun getPopularVoteList(): List<Vote>

suspend fun getPostCategoryConfig(): List<Category>
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ class GetLedgerListUseCase @Inject constructor(
ledgerRepository.getLedgerList(
title = title,
categoryIdList = categoryIdList,
fromStartAt = fromStartAt ?: LocalDateTime.now().minusYears(10),
toEndAt = toEndAt ?: LocalDateTime.now().plusYears(10),
fromStartAt = fromStartAt ?: LocalDateTime.now().minusYears(100),
toEndAt = toEndAt ?: LocalDateTime.now().plusYears(100),
page = page,
sort = sort,
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.susu.domain.usecase.vote

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

class GetPopularVoteListUseCase @Inject constructor(
private val voteRepository: VoteRepository,
) {
suspend operator fun invoke() = runCatchingIgnoreCancelled {
voteRepository.getPopularVoteList()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.susu.domain.usecase.vote

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

class GetPostCategoryConfigUseCase @Inject constructor(
private val voteRepository: VoteRepository,
) {
suspend operator fun invoke() = runCatchingIgnoreCancelled {
voteRepository.getPostCategoryConfig()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.susu.domain.usecase.vote

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

class GetVoteListUseCase @Inject constructor(
private val voteRepository: VoteRepository,
) {
suspend operator fun invoke(param: Param) = runCatchingIgnoreCancelled {
with(param) {
voteRepository.getVoteList(
content = content,
mine = mine,
sortType = sortType,
categoryId = categoryId,
page = page,
size = size,
sort = sort,
)
}
}

data class Param(
val content: String?,
val mine: Boolean?,
val sortType: String?,
val categoryId: Int?,
val page: Int?,
val size: Int? = null,
val sort: String?,
)
}
5 changes: 5 additions & 0 deletions feature/community/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
plugins {
alias(libs.plugins.susu.android.feature.compose)
alias(libs.plugins.kotlin.serialization)
}

android {
namespace = "com.susu.feature.community"
}

dependencies {
implementation(libs.kotlinx.serialization.json)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.susu.feature.community.community

import com.susu.core.model.Category
import com.susu.core.model.Vote
import com.susu.core.ui.base.SideEffect
import com.susu.core.ui.base.UiState
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf

data class CommunityState(
val categoryConfigList: PersistentList<Category> = persistentListOf(),
val selectedCategory: Category? = null,
val popularVoteList: PersistentList<Vote> = persistentListOf(),
val voteList: PersistentList<Vote> = persistentListOf(),
val isCheckedVotePopular: Boolean = false,
val isCheckShowMine: Boolean = false,
val isLoading: Boolean = false,
) : UiState

sealed interface CommunitySideEffect : SideEffect {
data class HandleException(val throwable: Throwable, val retry: () -> Unit) : CommunitySideEffect
}
Loading

0 comments on commit 02486b1

Please sign in to comment.