Skip to content

Commit

Permalink
Merge pull request #246 from mash-up-kr/feat/kk_count
Browse files Browse the repository at this point in the history
[Feat] 리액션 모아서 보내기
  • Loading branch information
hj1115hj authored Oct 3, 2024
2 parents 3de5426 + 5832ece commit 1014e91
Show file tree
Hide file tree
Showing 17 changed files with 215 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package team.ppac.common.kotlin.model

import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger

class ReactionState {
private val _isFirstClickEvent = AtomicBoolean(true)
private val _reactionCount = AtomicInteger(0)
private val _isUpdating = AtomicBoolean(false)
private var lastClickTime: Long = 0

val reactionCount: Int
get() = _reactionCount.get()

val isUpdating: Boolean
get() = _isUpdating.get()

val isFirstClickEvent: Boolean
get() = _isFirstClickEvent.get()

fun setIsFirstClickEvent(value: Boolean) {
_isFirstClickEvent.set(value)
}

fun addReactionCount(count: Int) {
_reactionCount.addAndGet(count)
}

fun startUpdate() {
_isUpdating.compareAndSet(false, true)
}

fun endUpdate() {
_isUpdating.set(false)
}

fun releaseState() {
_reactionCount.set(0)
_isFirstClickEvent.set(true)
}

fun isDoubleClickEvent(): Boolean {
val currentClickTime: Long = System.currentTimeMillis()
return if (currentClickTime - lastClickTime <= DOUBLE_CLICK_INTERVAL) {
true
} else {
lastClickTime = System.currentTimeMillis()
false
}
}

companion object {
private const val DOUBLE_CLICK_INTERVAL = 400
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package team.ppac.data.mapper

import team.ppac.domain.model.ReactionMeme
import team.ppac.remote.model.response.meme.ReactionMemeResponse

internal fun ReactionMemeResponse.toReactionMeme(): ReactionMeme = ReactionMeme(
count = count,
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package team.ppac.data.repository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import team.ppac.data.mapper.toMeme
import team.ppac.data.mapper.toReactionMeme
import team.ppac.data.paging.ITEMS_PER_PAGE
import team.ppac.data.paging.createPager
import team.ppac.domain.model.Meme
import team.ppac.domain.model.MemeWatchType
import team.ppac.domain.model.MemeWithPagination
import team.ppac.domain.model.ReactionMeme
import team.ppac.domain.repository.MemeRepository
import team.ppac.domain.repository.SavedMemeEvent
import team.ppac.remote.datasource.MemeDataSource
Expand Down Expand Up @@ -58,8 +60,8 @@ internal class MemeRepositoryImpl @Inject constructor(
)
}

override suspend fun reactMeme(memeId: String): Boolean {
return memeDataSource.reactMeme(memeId)
override suspend fun reactMeme(memeId: String, count: Int): ReactionMeme {
return memeDataSource.reactMeme(memeId, count).toReactionMeme()
}

override suspend fun watchMeme(memeId: String, watchType: MemeWatchType): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,15 @@ fun FarmemeWeakButton(
text: String = "",
textColor: Color = FarmemeTheme.textColor.primary,
withStar: Boolean = false,
isDebounceClick: Boolean = true,
onClick: () -> Unit = { },
icon: @Composable () -> Unit,
) {
Row(
modifier = modifier
.clip(FarmemeRadius.Radius25.shape)
.background(color = backgroundColor)
.noRippleClickable(onClick = onClick)
.noRippleClickable(onClick = onClick, isDebounceClick = isDebounceClick)
.padding(15.dp),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ import team.ppac.common.kotlin.model.MultipleEventsCutter
@SuppressLint("UnnecessaryComposedModifier")
fun Modifier.noRippleClickable(
enabled: Boolean = true,
isDebounceClick: Boolean = true,
onClickLabel: String? = null,
role: Role? = null,
onClick: () -> Unit,
onClick: () -> Unit
): Modifier = composed {
this then singleClickable(
indication = null,
enabled = enabled,
isDebounceClick = isDebounceClick,
onClickLabel = onClickLabel,
role = role,
onClick = onClick
Expand All @@ -31,37 +33,43 @@ fun Modifier.noRippleClickable(
@SuppressLint("UnnecessaryComposedModifier")
fun Modifier.rippleClickable(
rippleColor: Color = Color.Unspecified,
isDebounceClick: Boolean = true,
enabled: Boolean = true,
onClickLabel: String? = null,
role: Role? = null,
onClick: () -> Unit,
onClick: () -> Unit
): Modifier = composed {
this then singleClickable(
indication = rememberRipple(color = rippleColor),
enabled = enabled,
isDebounceClick = isDebounceClick,
onClickLabel = onClickLabel,
role = role,
onClick = onClick
onClick = onClick,
)
}

@SuppressLint("ModifierFactoryUnreferencedReceiver")
private fun Modifier.singleClickable(
indication: Indication?,
enabled: Boolean = true,
debounceMillis: Long = 300L,
isDebounceClick: Boolean = true,
onClickLabel: String? = null,
role: Role? = null,
debounceMillis: Long = 300L,
onClick: () -> Unit,
): Modifier = composed {
val multipleEventsCutter = remember { MultipleEventsCutter(debounceMillis) }

clickable(
interactionSource = remember { MutableInteractionSource() },
indication = indication,
enabled = enabled,
onClickLabel = onClickLabel,
role = role,
onClick = { multipleEventsCutter.processEvent(onClick) },
onClick = if (isDebounceClick) {
{ multipleEventsCutter.processEvent(onClick) }
} else {
{ onClick() }
},
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package team.ppac.domain.model

data class ReactionMeme (
val count: Int
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import kotlinx.coroutines.flow.Flow
import team.ppac.domain.model.Meme
import team.ppac.domain.model.MemeWatchType
import team.ppac.domain.model.MemeWithPagination
import team.ppac.domain.model.ReactionMeme

interface MemeRepository {
suspend fun getMeme(memeId: String): Meme
Expand All @@ -14,8 +15,7 @@ interface MemeRepository {
keyword: String,
getCurrentPage: (Int) -> Unit
): MemeWithPagination

suspend fun reactMeme(memeId: String): Boolean
suspend fun reactMeme(memeId: String, count: Int): ReactionMeme
suspend fun watchMeme(
memeId: String,
watchType: MemeWatchType,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package team.ppac.domain.usecase

import team.ppac.domain.model.ReactionMeme
import team.ppac.domain.repository.MemeRepository
import javax.inject.Inject

interface ReactMemeUseCase {
suspend operator fun invoke(memeId: String): Boolean
suspend operator fun invoke(memeId: String, count: Int): ReactionMeme
}

internal class ReactMemeUseCaseImpl @Inject constructor(
private val memeRepository: MemeRepository,
) : ReactMemeUseCase {
override suspend fun invoke(memeId: String): Boolean {
return memeRepository.reactMeme(memeId)
override suspend fun invoke(memeId: String, count: Int): ReactionMeme {
return memeRepository.reactMeme(memeId, count)
}
}
8 changes: 7 additions & 1 deletion core/remote/src/main/kotlin/team/ppac/remote/api/MemeApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ package team.ppac.remote.api

import okhttp3.MultipartBody
import okhttp3.RequestBody
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.Multipart
import retrofit2.http.POST
import retrofit2.http.Part
import retrofit2.http.Path
import retrofit2.http.Query
import team.ppac.remote.model.request.meme.ReactMemeRequest
import team.ppac.remote.model.response.meme.MemeResponse
import team.ppac.remote.model.response.meme.ReactionMemeResponse
import team.ppac.remote.model.response.user.MemesResponse
import team.ppac.remote.model.response.meme.UploadMemeResponse

Expand Down Expand Up @@ -37,7 +40,10 @@ internal interface MemeApi {
): MemesResponse

@POST("/api/meme/{memeId}/reaction")
suspend fun reactMeme(@Path("memeId") memeId: String): Boolean
suspend fun reactMeme(
@Path("memeId") memeId: String,
@Body reactMemeRequest: ReactMemeRequest
): ReactionMemeResponse

@POST("/api/meme/{memeId}/watch/{type}")
suspend fun watchMeme(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package team.ppac.remote.datasource

import team.ppac.remote.model.response.meme.MemeResponse
import team.ppac.remote.model.response.meme.ReactionMemeResponse
import team.ppac.remote.model.response.user.MemesResponse

interface MemeDataSource {
Expand All @@ -13,7 +14,7 @@ interface MemeDataSource {
page: Int,
size: Int,
): MemesResponse
suspend fun reactMeme(memeId: String): Boolean
suspend fun reactMeme(memeId: String, count: Int): ReactionMemeResponse
suspend fun watchMeme(
memeId: String,
type: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import team.ppac.remote.api.MemeApi
import team.ppac.remote.datasource.MemeDataSource
import team.ppac.remote.model.request.meme.ReactMemeRequest
import team.ppac.remote.model.response.meme.MemeResponse
import team.ppac.remote.model.response.meme.ReactionMemeResponse
import team.ppac.remote.model.response.user.MemesResponse
import java.io.File
import java.io.FileOutputStream
Expand Down Expand Up @@ -43,8 +45,8 @@ internal class MemeDataSourceImpl @Inject constructor(
return memeApi.getSearchMemes(keyword, page, size)
}

override suspend fun reactMeme(memeId: String): Boolean {
return memeApi.reactMeme(memeId)
override suspend fun reactMeme(memeId: String, count: Int): ReactionMemeResponse {
return memeApi.reactMeme(memeId, reactMemeRequest = ReactMemeRequest(count))
}

override suspend fun watchMeme(memeId: String, type: String): Boolean {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package team.ppac.remote.model.request.meme

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass

@JsonClass(generateAdapter = true)
data class ReactMemeRequest (
@field:Json(name = "count")
val count: Int,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package team.ppac.remote.model.response.meme

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass

@JsonClass(generateAdapter = true)
data class ReactionMemeResponse (
@field:Json(name = "count")
val count: Int,
)
Loading

0 comments on commit 1014e91

Please sign in to comment.