사용자가 컨텐츠에 대해 좋아요 했을때
컨텐츠가 보이는 어떤 화면에서든 이벤트를 받아와 UI 업데이트 하려고 한다.
1. 도메인 모듈에 인터페이스 모델 추가
sealed interface ContentEvent {
data class AddLike(
val id: Int
) : ContentEvent
data class RemoveLike(
val id: Int
) : ContentEvent
}
레포지토리에 SharedFlow 생성
interface ContentRepository {
val contentEvent: SharedFlow<ContentEvent>
}
internal class ContentRepositoryImpl @Inject constructor(
private val remote: ContentRemoteDataSource,
) : ContentRepository {
private val _contentEvent: MutableSharedFlow<ContentEvent> = MutableSharedFlow()
override val contentEvent = _contentEvent.asSharedFlow()
override suspend fun updateLike(id: Int): Result<Boolean> {
return remote.updateLike(id).onSuccess { isLiked ->
if (isLiked) {
_contentEvent.emit(ContentEvent.AddLike(id))
} else {
_contentEvent.emit(ContentEvent.RemoveLike(id))
}
}
}
}
API 통신이 성공하면 contentEvent에 전파 ( isLiked 는 서버 Response )
UseCase
@Singleton
class FetchContentEventUseCase @Inject constructor(
private val repository: ContentRepository
) {
operator fun invoke() = repository.contentEvent
}
컨텐츠가 보이는 뷰모델들에 대해 해당 UseCase Inject
fetchCommentEventUseCase: FetchCommentEventUseCase
init{
fetchContentEventUseCase.invoke()
.onEach {
when (it) {
is ContentEvent.AddLike -> {
fetchLike(it.id, true)
}
is ContentEvent.RemoveLike -> {
fetchLike(it.id, false)
}
}
}.launchIn(viewModelScope)
}
private fun fetchLike(id: Int, isLike: Boolean) = launch {
updateState {
copy(
contents = this.contents.edit {
val index = indexOfFirst { it.id == id }.takeIf { it > -1 } ?: return@edit
val content = this[index]
this[index] = content.copy(
isLike = isLike,
likeCount = if (isLike) content.likeCount + 1 else content.likeCount - 1
)
})
}
}
그 다음 리스트를 변경해주면 된다.
'Android' 카테고리의 다른 글
QR코드 스캔 커스텀 ( + 플래시 ) (0) | 2023.01.04 |
---|---|
[CI/CD] fastlane : App Distribution + Slack Message (0) | 2022.11.24 |
build.gradle에 정의한 manifestPlaceholders 값 주입 받기 (0) | 2022.11.05 |
카카오톡 채팅화면 키보드 옵션창 구현 (0) | 2022.10.09 |
Gson으로 sealed class 로 맵핑하기 (0) | 2022.10.04 |