From 9039bd3000fd4e2cbc636aad547f213d48a75b80 Mon Sep 17 00:00:00 2001 From: hoyahozz <85336456+hoyahozz@users.noreply.github.com> Date: Sat, 28 May 2022 22:13:26 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat=20-=20BaseViewModel=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/yapp/growth/base/BaseViewModel.kt | 51 +++++++++++++++++++ .../java/com/yapp/growth/base/ViewEvent.kt | 4 ++ .../com/yapp/growth/base/ViewSideEffect.kt | 4 ++ .../java/com/yapp/growth/base/ViewState.kt | 4 ++ 4 files changed, 63 insertions(+) create mode 100644 presentation/src/main/java/com/yapp/growth/base/BaseViewModel.kt create mode 100644 presentation/src/main/java/com/yapp/growth/base/ViewEvent.kt create mode 100644 presentation/src/main/java/com/yapp/growth/base/ViewSideEffect.kt create mode 100644 presentation/src/main/java/com/yapp/growth/base/ViewState.kt diff --git a/presentation/src/main/java/com/yapp/growth/base/BaseViewModel.kt b/presentation/src/main/java/com/yapp/growth/base/BaseViewModel.kt new file mode 100644 index 00000000..80c1395b --- /dev/null +++ b/presentation/src/main/java/com/yapp/growth/base/BaseViewModel.kt @@ -0,0 +1,51 @@ +package com.yapp.growth.base + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.* +import kotlinx.coroutines.launch + +abstract class BaseViewModel( + initialState: S +) : ViewModel() { + + abstract fun handleEvents(event: E) + + private val _viewState: MutableStateFlow = MutableStateFlow(initialState) + val viewState = _viewState.asStateFlow() + + private val currentState: S + get() = _viewState.value + + private val _effect: Channel = Channel() + val effect = _effect.receiveAsFlow() + + private val _event: MutableSharedFlow = MutableSharedFlow() + + init { + subscribeToEvents() + } + + private fun subscribeToEvents() { + viewModelScope.launch { + _event.collect { + handleEvents(it) + } + } + } + + protected fun setState(reducer: S.() -> S) { + val newState = currentState.reducer() + _viewState.value = newState + } + + protected fun setEffect(builder: () -> A) { + val effectValue = builder() + viewModelScope.launch { _effect.send(effectValue) } + } + + open fun setEvent(event : E) { + viewModelScope.launch { _event.emit(event) } + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/yapp/growth/base/ViewEvent.kt b/presentation/src/main/java/com/yapp/growth/base/ViewEvent.kt new file mode 100644 index 00000000..5fb11fd4 --- /dev/null +++ b/presentation/src/main/java/com/yapp/growth/base/ViewEvent.kt @@ -0,0 +1,4 @@ +package com.yapp.growth.base + +interface ViewEvent { +} \ No newline at end of file diff --git a/presentation/src/main/java/com/yapp/growth/base/ViewSideEffect.kt b/presentation/src/main/java/com/yapp/growth/base/ViewSideEffect.kt new file mode 100644 index 00000000..f4f4a857 --- /dev/null +++ b/presentation/src/main/java/com/yapp/growth/base/ViewSideEffect.kt @@ -0,0 +1,4 @@ +package com.yapp.growth.base + +interface ViewSideEffect { +} \ No newline at end of file diff --git a/presentation/src/main/java/com/yapp/growth/base/ViewState.kt b/presentation/src/main/java/com/yapp/growth/base/ViewState.kt new file mode 100644 index 00000000..9783f958 --- /dev/null +++ b/presentation/src/main/java/com/yapp/growth/base/ViewState.kt @@ -0,0 +1,4 @@ +package com.yapp.growth.base + +interface ViewState { +} \ No newline at end of file From e16fc3b05c73424587d7508e2e614047d3993144 Mon Sep 17 00:00:00 2001 From: hoyahozz <85336456+hoyahozz@users.noreply.github.com> Date: Sat, 28 May 2022 22:14:01 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feat=20-=20=EC=83=98=ED=94=8C=20ViewModel,?= =?UTF-8?q?=20Contract=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yapp/growth/ui/sample/SampleContract.kt | 22 +++++++++++++++ .../yapp/growth/ui/sample/SampleViewModel.kt | 27 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 presentation/src/main/java/com/yapp/growth/ui/sample/SampleContract.kt create mode 100644 presentation/src/main/java/com/yapp/growth/ui/sample/SampleViewModel.kt diff --git a/presentation/src/main/java/com/yapp/growth/ui/sample/SampleContract.kt b/presentation/src/main/java/com/yapp/growth/ui/sample/SampleContract.kt new file mode 100644 index 00000000..5bea42a3 --- /dev/null +++ b/presentation/src/main/java/com/yapp/growth/ui/sample/SampleContract.kt @@ -0,0 +1,22 @@ +package com.yapp.growth.ui.sample + +import com.yapp.growth.base.ViewEvent +import com.yapp.growth.base.ViewSideEffect +import com.yapp.growth.base.ViewState + +class SampleContract { + + data class SampleViewState( + val isLoading: Boolean = false + ) : ViewState + + sealed class SampleViewSideEffect : ViewSideEffect { + object NavigateToAnyScreen : SampleViewSideEffect() + data class ShowToast(val msg: String) : SampleViewSideEffect() + } + + sealed class SampleViewEvent : ViewEvent { + object OnAnyButtonClicked : SampleViewEvent() + } + +} \ No newline at end of file diff --git a/presentation/src/main/java/com/yapp/growth/ui/sample/SampleViewModel.kt b/presentation/src/main/java/com/yapp/growth/ui/sample/SampleViewModel.kt new file mode 100644 index 00000000..6dd91cb4 --- /dev/null +++ b/presentation/src/main/java/com/yapp/growth/ui/sample/SampleViewModel.kt @@ -0,0 +1,27 @@ +package com.yapp.growth.ui.sample + +import com.yapp.growth.base.BaseViewModel +import com.yapp.growth.domain.usecase.UseCase +import com.yapp.growth.ui.sample.SampleContract.* + +class SampleViewModel( + private val useCase: UseCase +) : BaseViewModel( + SampleViewState() +) { + + fun anyFunction() { + // anything do . . . + setEffect { SampleViewSideEffect.NavigateToAnyScreen } + setState { copy(isLoading = false) } + } + + override fun handleEvents(event: SampleViewEvent) { + when (event) { + is SampleViewEvent.OnAnyButtonClicked -> { + setState { copy(isLoading = true) } + anyFunction() + } + } + } +} \ No newline at end of file From d5e40616aa8efc2346ca56018ade2623aa34e8ec Mon Sep 17 00:00:00 2001 From: hoyahozz <85336456+hoyahozz@users.noreply.github.com> Date: Thu, 2 Jun 2022 18:32:45 +0900 Subject: [PATCH 3/6] =?UTF-8?q?refactor=20-=20=ED=95=A9=EC=9D=98=EB=90=9C?= =?UTF-8?q?=20=EC=BB=A8=EB=B2=A4=EC=85=98=EC=97=90=20=EB=94=B0=EB=9D=BC=20?= =?UTF-8?q?=EC=9D=B4=EB=B2=A4=ED=8A=B8,=20=EC=82=AC=EC=9D=B4=EB=93=9C=20?= =?UTF-8?q?=EC=9D=B4=ED=8E=99=ED=8A=B8=20=EB=AA=85=EC=B9=AD=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/yapp/growth/ui/sample/SampleContract.kt | 10 +++++----- .../java/com/yapp/growth/ui/sample/SampleViewModel.kt | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/presentation/src/main/java/com/yapp/growth/ui/sample/SampleContract.kt b/presentation/src/main/java/com/yapp/growth/ui/sample/SampleContract.kt index 5bea42a3..1ae65498 100644 --- a/presentation/src/main/java/com/yapp/growth/ui/sample/SampleContract.kt +++ b/presentation/src/main/java/com/yapp/growth/ui/sample/SampleContract.kt @@ -10,13 +10,13 @@ class SampleContract { val isLoading: Boolean = false ) : ViewState - sealed class SampleViewSideEffect : ViewSideEffect { - object NavigateToAnyScreen : SampleViewSideEffect() - data class ShowToast(val msg: String) : SampleViewSideEffect() + sealed class SampleSideEffect : ViewSideEffect { + object NavigateToAnyScreen : SampleSideEffect() + data class ShowToast(val msg: String) : SampleSideEffect() } - sealed class SampleViewEvent : ViewEvent { - object OnAnyButtonClicked : SampleViewEvent() + sealed class SampleEvent : ViewEvent { + object OnAnyButtonClicked : SampleEvent() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/yapp/growth/ui/sample/SampleViewModel.kt b/presentation/src/main/java/com/yapp/growth/ui/sample/SampleViewModel.kt index 6dd91cb4..3cb50eb8 100644 --- a/presentation/src/main/java/com/yapp/growth/ui/sample/SampleViewModel.kt +++ b/presentation/src/main/java/com/yapp/growth/ui/sample/SampleViewModel.kt @@ -6,19 +6,19 @@ import com.yapp.growth.ui.sample.SampleContract.* class SampleViewModel( private val useCase: UseCase -) : BaseViewModel( +) : BaseViewModel( SampleViewState() ) { fun anyFunction() { // anything do . . . - setEffect { SampleViewSideEffect.NavigateToAnyScreen } + setEffect { SampleSideEffect.NavigateToAnyScreen } setState { copy(isLoading = false) } } - override fun handleEvents(event: SampleViewEvent) { + override fun handleEvents(event: SampleEvent) { when (event) { - is SampleViewEvent.OnAnyButtonClicked -> { + is SampleEvent.OnAnyButtonClicked -> { setState { copy(isLoading = true) } anyFunction() } From 66079bf5fd25af07d58fa1cc1ba247c037b965f0 Mon Sep 17 00:00:00 2001 From: hoyahozz <85336456+hoyahozz@users.noreply.github.com> Date: Thu, 2 Jun 2022 21:37:47 +0900 Subject: [PATCH 4/6] =?UTF-8?q?fix=20-=20=EC=9D=B4=ED=8E=99=ED=8A=B8?= =?UTF-8?q?=EA=B0=80=20=ED=95=9C=EB=B2=88=EC=97=90=20=EC=97=AC=EB=9F=AC=20?= =?UTF-8?q?=EB=B2=88=20=EB=93=A4=EC=96=B4=EC=98=A4=EB=8A=94=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=EB=A5=BC=20=EB=8C=80=EB=B9=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/yapp/growth/base/BaseViewModel.kt | 7 ++++--- .../main/java/com/yapp/growth/ui/sample/SampleViewModel.kt | 7 +++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/presentation/src/main/java/com/yapp/growth/base/BaseViewModel.kt b/presentation/src/main/java/com/yapp/growth/base/BaseViewModel.kt index 80c1395b..6746c30c 100644 --- a/presentation/src/main/java/com/yapp/growth/base/BaseViewModel.kt +++ b/presentation/src/main/java/com/yapp/growth/base/BaseViewModel.kt @@ -40,9 +40,10 @@ abstract class BaseViewModel( _viewState.value = newState } - protected fun setEffect(builder: () -> A) { - val effectValue = builder() - viewModelScope.launch { _effect.send(effectValue) } + protected fun setEffect(vararg builder: () -> A) { + for (effectValue in builder) { + viewModelScope.launch { _effect.send(effectValue()) } + } } open fun setEvent(event : E) { diff --git a/presentation/src/main/java/com/yapp/growth/ui/sample/SampleViewModel.kt b/presentation/src/main/java/com/yapp/growth/ui/sample/SampleViewModel.kt index 3cb50eb8..82ef4d2e 100644 --- a/presentation/src/main/java/com/yapp/growth/ui/sample/SampleViewModel.kt +++ b/presentation/src/main/java/com/yapp/growth/ui/sample/SampleViewModel.kt @@ -10,9 +10,12 @@ class SampleViewModel( SampleViewState() ) { - fun anyFunction() { + private fun anyFunction() { // anything do . . . - setEffect { SampleSideEffect.NavigateToAnyScreen } + setEffect( + { SampleSideEffect.NavigateToAnyScreen }, + { SampleSideEffect.ShowToast("This is Sample Data") } + ) setState { copy(isLoading = false) } } From 301a42ccc019a155989ffce0a34f37df8d7bb093 Mon Sep 17 00:00:00 2001 From: hoyahozz <85336456+hoyahozz@users.noreply.github.com> Date: Thu, 2 Jun 2022 21:38:35 +0900 Subject: [PATCH 5/6] =?UTF-8?q?refactor=20-=20=EC=9D=B4=ED=8E=99=ED=8A=B8,?= =?UTF-8?q?=20=EC=83=81=ED=83=9C=20=EA=B0=B1=EC=8B=A0=EC=97=90=20=EA=B4=80?= =?UTF-8?q?=ED=95=9C=20=ED=95=A8=EC=88=98=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/yapp/growth/base/BaseViewModel.kt | 4 ++-- .../main/java/com/yapp/growth/ui/sample/SampleViewModel.kt | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/presentation/src/main/java/com/yapp/growth/base/BaseViewModel.kt b/presentation/src/main/java/com/yapp/growth/base/BaseViewModel.kt index 6746c30c..82eb53bc 100644 --- a/presentation/src/main/java/com/yapp/growth/base/BaseViewModel.kt +++ b/presentation/src/main/java/com/yapp/growth/base/BaseViewModel.kt @@ -35,12 +35,12 @@ abstract class BaseViewModel( } } - protected fun setState(reducer: S.() -> S) { + protected fun updateState(reducer: S.() -> S) { val newState = currentState.reducer() _viewState.value = newState } - protected fun setEffect(vararg builder: () -> A) { + protected fun sendEffect(vararg builder: () -> A) { for (effectValue in builder) { viewModelScope.launch { _effect.send(effectValue()) } } diff --git a/presentation/src/main/java/com/yapp/growth/ui/sample/SampleViewModel.kt b/presentation/src/main/java/com/yapp/growth/ui/sample/SampleViewModel.kt index 82ef4d2e..d0e033b5 100644 --- a/presentation/src/main/java/com/yapp/growth/ui/sample/SampleViewModel.kt +++ b/presentation/src/main/java/com/yapp/growth/ui/sample/SampleViewModel.kt @@ -12,17 +12,17 @@ class SampleViewModel( private fun anyFunction() { // anything do . . . - setEffect( + sendEffect( { SampleSideEffect.NavigateToAnyScreen }, { SampleSideEffect.ShowToast("This is Sample Data") } ) - setState { copy(isLoading = false) } + updateState { copy(isLoading = false) } } override fun handleEvents(event: SampleEvent) { when (event) { is SampleEvent.OnAnyButtonClicked -> { - setState { copy(isLoading = true) } + updateState { copy(isLoading = true) } anyFunction() } } From b24f39b14a912a148859a2deea3f51356cc10a3b Mon Sep 17 00:00:00 2001 From: hoyahozz <85336456+hoyahozz@users.noreply.github.com> Date: Thu, 2 Jun 2022 21:45:37 +0900 Subject: [PATCH 6/6] =?UTF-8?q?refactor=20-=20=EC=9D=B4=EB=B2=A4=ED=8A=B8?= =?UTF-8?q?=EC=97=90=20=EA=B4=80=ED=95=9C=20=EC=A4=91=EC=B2=A9=20=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EB=A6=BC=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/yapp/growth/base/BaseViewModel.kt | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/presentation/src/main/java/com/yapp/growth/base/BaseViewModel.kt b/presentation/src/main/java/com/yapp/growth/base/BaseViewModel.kt index 82eb53bc..e8f27464 100644 --- a/presentation/src/main/java/com/yapp/growth/base/BaseViewModel.kt +++ b/presentation/src/main/java/com/yapp/growth/base/BaseViewModel.kt @@ -23,18 +23,6 @@ abstract class BaseViewModel( private val _event: MutableSharedFlow = MutableSharedFlow() - init { - subscribeToEvents() - } - - private fun subscribeToEvents() { - viewModelScope.launch { - _event.collect { - handleEvents(it) - } - } - } - protected fun updateState(reducer: S.() -> S) { val newState = currentState.reducer() _viewState.value = newState @@ -47,6 +35,10 @@ abstract class BaseViewModel( } open fun setEvent(event : E) { - viewModelScope.launch { _event.emit(event) } + deliverEvent(event) + } + + private fun deliverEvent(event : E) = viewModelScope.launch { + handleEvents(event) } } \ No newline at end of file