From 204b027b7dde12b0f79ade2cd51e3baec5efd048 Mon Sep 17 00:00:00 2001 From: HamBP Date: Thu, 16 Jan 2025 23:22:23 +0900 Subject: [PATCH] =?UTF-8?q?feat=20:=20data=20layer=20=EC=A0=9C=EC=99=B8=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../boolti/data/datasource/PopupDataSource.kt | 13 +++++------- .../data/repository/PopupRepositoryImpl.kt | 10 ++++++++++ .../domain/repository/PopupRepository.kt | 2 ++ .../boolti/domain/usecase/GetPopupUseCase.kt | 20 +++++++++++++++++++ .../boolti/presentation/component/BTDialog.kt | 7 ++++++- .../presentation/screen/show/ShowScreen.kt | 16 +++++++++++++-- .../presentation/screen/show/ShowViewModel.kt | 17 ++++++++-------- 7 files changed, 66 insertions(+), 19 deletions(-) create mode 100644 domain/src/main/java/com/nexters/boolti/domain/usecase/GetPopupUseCase.kt diff --git a/data/src/main/java/com/nexters/boolti/data/datasource/PopupDataSource.kt b/data/src/main/java/com/nexters/boolti/data/datasource/PopupDataSource.kt index 54592530d..25f746c34 100644 --- a/data/src/main/java/com/nexters/boolti/data/datasource/PopupDataSource.kt +++ b/data/src/main/java/com/nexters/boolti/data/datasource/PopupDataSource.kt @@ -1,9 +1,6 @@ package com.nexters.boolti.data.datasource import android.content.Context -import androidx.datastore.core.DataStore -import androidx.datastore.preferences.core.Preferences -import androidx.datastore.preferences.preferencesDataStore import com.nexters.boolti.data.network.api.PopupService import com.nexters.boolti.data.network.response.PopupResponse import javax.inject.Inject @@ -12,14 +9,14 @@ internal class PopupDataSource @Inject constructor( private val service: PopupService, private val context: Context, ) { -// private val dataStore: DataStore by context.pre - suspend fun getPopup(): PopupResponse = service.getPopup() - suspend fun shouldShowPopup(): Boolean { + + suspend fun shouldShowEvent(): Boolean { + // todo return true } - suspend fun hidePopupToday() { - + suspend fun hideEventToday() { + // todo } } \ No newline at end of file diff --git a/data/src/main/java/com/nexters/boolti/data/repository/PopupRepositoryImpl.kt b/data/src/main/java/com/nexters/boolti/data/repository/PopupRepositoryImpl.kt index 049a35a59..b59745331 100644 --- a/data/src/main/java/com/nexters/boolti/data/repository/PopupRepositoryImpl.kt +++ b/data/src/main/java/com/nexters/boolti/data/repository/PopupRepositoryImpl.kt @@ -2,12 +2,22 @@ package com.nexters.boolti.data.repository import com.nexters.boolti.data.datasource.PopupDataSource import com.nexters.boolti.domain.repository.PopupRepository +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow import javax.inject.Inject internal class PopupRepositoryImpl @Inject constructor( private val dataSource: PopupDataSource, ) : PopupRepository { + + override fun shouldShowEvent(): Flow = flow { + emit(true) // TODO : preference에서 가져오기 + } + + override fun hideEventToday(): Flow = flow { + // TODO : preference에 저장 + } + override fun getPopup() = flow { emit(dataSource.getPopup().toDomain()) } diff --git a/domain/src/main/java/com/nexters/boolti/domain/repository/PopupRepository.kt b/domain/src/main/java/com/nexters/boolti/domain/repository/PopupRepository.kt index 85117ea00..d9c6d842c 100644 --- a/domain/src/main/java/com/nexters/boolti/domain/repository/PopupRepository.kt +++ b/domain/src/main/java/com/nexters/boolti/domain/repository/PopupRepository.kt @@ -4,5 +4,7 @@ import com.nexters.boolti.domain.model.Popup import kotlinx.coroutines.flow.Flow interface PopupRepository { + fun shouldShowEvent(): Flow + fun hideEventToday(): Flow fun getPopup(): Flow } \ No newline at end of file diff --git a/domain/src/main/java/com/nexters/boolti/domain/usecase/GetPopupUseCase.kt b/domain/src/main/java/com/nexters/boolti/domain/usecase/GetPopupUseCase.kt new file mode 100644 index 000000000..ed799c496 --- /dev/null +++ b/domain/src/main/java/com/nexters/boolti/domain/usecase/GetPopupUseCase.kt @@ -0,0 +1,20 @@ +package com.nexters.boolti.domain.usecase + +import com.nexters.boolti.domain.model.Popup +import com.nexters.boolti.domain.repository.PopupRepository +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.first +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class GetPopupUseCase @Inject constructor( + private val popupRepository: PopupRepository, +) { + operator fun invoke(): Flow = popupRepository + .getPopup() + .filter { popup -> + popup is Popup.Notice || popupRepository.shouldShowEvent().first() + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/nexters/boolti/presentation/component/BTDialog.kt b/presentation/src/main/java/com/nexters/boolti/presentation/component/BTDialog.kt index 61dede454..5a8072efc 100644 --- a/presentation/src/main/java/com/nexters/boolti/presentation/component/BTDialog.kt +++ b/presentation/src/main/java/com/nexters/boolti/presentation/component/BTDialog.kt @@ -121,8 +121,11 @@ fun NoticeDialog( title: String, content: String, emphasizedText: String = "", + onDismiss: () -> Unit, ) { - BTDialog { + BTDialog( + onDismiss = onDismiss, + ) { Column( horizontalAlignment = Alignment.CenterHorizontally, ) { @@ -196,6 +199,7 @@ fun NoticeDialogPreview() { NoticeDialog( title = "맴뱀페이 결제 불가 안내", content = "이용에 불편을 드려 죄송합니다. 서비스가 정상화되는 즉시 다시 안내드릴 예정이오니, 다른 결제수단을 이용해 주시면 감사하겠습니다.", + onDismiss = {} ) } } @@ -210,6 +214,7 @@ fun NoticeEmphasizedDialogPreview() { title = "맴뱀페이 결제 불가 안내", content = "이용에 불편을 드려 죄송합니다. 서비스가 정상화되는 즉시 다시 안내드릴 예정이오니, 다른 결제수단을 이용해 주시면 감사하겠습니다.", emphasizedText = "현재 야근 중인 관계로 코딩이 영구적으로 불가합니다.", + onDismiss = {} ) } } diff --git a/presentation/src/main/java/com/nexters/boolti/presentation/screen/show/ShowScreen.kt b/presentation/src/main/java/com/nexters/boolti/presentation/screen/show/ShowScreen.kt index 1c4c235fb..85938734f 100644 --- a/presentation/src/main/java/com/nexters/boolti/presentation/screen/show/ShowScreen.kt +++ b/presentation/src/main/java/com/nexters/boolti/presentation/screen/show/ShowScreen.kt @@ -60,8 +60,10 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.nexters.boolti.domain.model.Popup import com.nexters.boolti.presentation.R import com.nexters.boolti.presentation.component.BusinessInformation +import com.nexters.boolti.presentation.component.NoticeDialog import com.nexters.boolti.presentation.component.ShowFeed import com.nexters.boolti.presentation.component.StatusBarCover +import com.nexters.boolti.presentation.extension.extractEmphasizedText import com.nexters.boolti.presentation.extension.toPx import com.nexters.boolti.presentation.theme.Grey05 import com.nexters.boolti.presentation.theme.Grey15 @@ -193,12 +195,22 @@ fun ShowScreen( EventDialog( imageUrl = popup.imageUrl, actionUrl = popup.eventUrl, - onDismiss = { popupToShow = null }, + onDismiss = { hideToday -> + popupToShow = null + if (hideToday) viewModel.hideEventToday() + }, ) } is Popup.Notice -> { - TODO("implement notice dialog") + val (emphasizedText, remainingText) = popup.description.extractEmphasizedText() + + NoticeDialog( + title = popup.title, + emphasizedText = emphasizedText, + content = remainingText, + onDismiss = { popupToShow = null }, + ) } } } diff --git a/presentation/src/main/java/com/nexters/boolti/presentation/screen/show/ShowViewModel.kt b/presentation/src/main/java/com/nexters/boolti/presentation/screen/show/ShowViewModel.kt index 68acbc993..d8bf83a3f 100644 --- a/presentation/src/main/java/com/nexters/boolti/presentation/screen/show/ShowViewModel.kt +++ b/presentation/src/main/java/com/nexters/boolti/presentation/screen/show/ShowViewModel.kt @@ -5,9 +5,9 @@ import com.nexters.boolti.domain.model.User import com.nexters.boolti.domain.repository.AuthRepository import com.nexters.boolti.domain.repository.PopupRepository import com.nexters.boolti.domain.repository.ShowRepository +import com.nexters.boolti.domain.usecase.GetPopupUseCase import com.nexters.boolti.presentation.base.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow @@ -15,8 +15,6 @@ import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.filter -import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn @@ -30,6 +28,7 @@ import javax.inject.Inject class ShowViewModel @Inject constructor( private val showRepository: ShowRepository, private val popupRepository: PopupRepository, + private val getPopupUseCase: GetPopupUseCase, authRepository: AuthRepository, ) : BaseViewModel() { val user: StateFlow = authRepository.cachedUser.stateIn( @@ -70,13 +69,15 @@ class ShowViewModel @Inject constructor( _uiState.update { it.copy(keyword = newKeyword) } } - @OptIn(ExperimentalCoroutinesApi::class) private fun fetchPopup() { - popupRepository - .shouldShowPopup() - .filter { it } - .flatMapLatest { popupRepository.getPopup() } + getPopupUseCase() .onEach { popup -> sendEvent(ShowEvent.ShowPopup(popup)) } .launchIn(viewModelScope + recordExceptionHandler) } + + fun hideEventToday() { + popupRepository + .hideEventToday() + .launchIn(viewModelScope + recordExceptionHandler) + } }