Skip to content
This repository has been archived by the owner on Feb 17, 2024. It is now read-only.

Commit

Permalink
rename effect to event (#76)
Browse files Browse the repository at this point in the history
* rename effect to event

* UiStateRendererをさくじょ
  • Loading branch information
okuzawats authored Jan 19, 2023
1 parent 38af3d0 commit 99ae17a
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow

/**
* a subclass of [androidx.lifecycle.ViewModel] which has state and effect.
* a subclass of [androidx.lifecycle.ViewModel] which has state and event.
*
* @param STATE type that represent the state of the ViewModel.
* @param EFFECT type that represent the effect the ViewModel has.
* @param EVENT type that represent the event the ViewModel may have.
*/
abstract class ViewModel<STATE: Any, EFFECT: Any> : androidx.lifecycle.ViewModel() {
abstract class ViewModel<STATE: Any, EVENT: Any> : androidx.lifecycle.ViewModel() {
private val _state: MutableStateFlow<STATE> by lazy {
MutableStateFlow(initialState())
}
Expand All @@ -22,14 +22,14 @@ abstract class ViewModel<STATE: Any, EFFECT: Any> : androidx.lifecycle.ViewModel
*/
val state: Flow<STATE> get() = _state.asStateFlow()

private val _effect: MutableSharedFlow<EFFECT> by lazy {
private val _event: MutableSharedFlow<EVENT> by lazy {
MutableSharedFlow()
}

/**
* effect that the ViewModel has.
* event that the ViewModel may have.
*/
val effect: Flow<EFFECT> get() = _effect.asSharedFlow()
val event: Flow<EVENT> get() = _event.asSharedFlow()

/**
* initial state of the ViewModel.
Expand All @@ -44,9 +44,9 @@ abstract class ViewModel<STATE: Any, EFFECT: Any> : androidx.lifecycle.ViewModel
}

/**
* do effect
* an event occur
*/
internal suspend fun doEffect(effect: EFFECT) {
_effect.emit(effect)
internal suspend fun onNewEvent(event: EVENT) {
_event.emit(event)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@ import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.lifecycle.lifecycleScope
import com.okuzawats.cleanarchitecture.feature.dog.composable.ErrorView
import com.okuzawats.cleanarchitecture.feature.dog.composable.ImageView
import com.okuzawats.cleanarchitecture.feature.dog.composable.InitialView
import com.okuzawats.cleanarchitecture.feature.dog.composable.LoadingView
import com.okuzawats.cleanarchitecture.feature.dog.mapper.PresentationToUiMapper
import com.okuzawats.cleanarchitecture.feature.dog.navigation.MainNavigator
import com.okuzawats.cleanarchitecture.feature.dog.viewmodel.MainViewModel
Expand All @@ -26,9 +33,6 @@ class MainActivity : ComponentActivity() {
@Inject
internal lateinit var presentationToUiMapper: PresentationToUiMapper

@Inject
internal lateinit var uiStateRenderer: UiStateRenderer

@Inject
internal lateinit var mainNavigator: MainNavigator

Expand All @@ -37,8 +41,8 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

viewModel.effect.onEach { effect ->
when (presentationToUiMapper.toUi(effect)) {
viewModel.event.onEach { event ->
when (presentationToUiMapper.toUi(event)) {
is UiEvent.NavigateToLicense -> {
mainNavigator.toLicense()
}
Expand All @@ -54,13 +58,22 @@ class MainActivity : ComponentActivity() {
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
viewState.collectAsState(initial = UiState.initial())
.let {
uiStateRenderer.RenderAsComposable(
uiState = it,
onLicenseClicked = viewModel::onLicenseAction,
)
val state = viewState.collectAsState(initial = UiState.initial())
when (state.value) {
is UiState.Initial -> InitialView()
is UiState.Loading -> LoadingView()
is UiState.Image -> {
Column {
Button(onClick = viewModel::onLicenseAction) {
Text(text = "LICENSE")
}
ImageView(
imageUrl = (state.value as UiState.Image).url,
)
}
}
is UiState.Error -> ErrorView()
}
}
}
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ class MainViewModel @Inject constructor(
onNewState(MainViewModelState.Loading)
getRandomDogImageUseCase()
.map(domainToPresentationMapper::toPresentation)
.map(MainViewModelState.Companion::from)
.map(MainViewModelState::from)
.onEach(::onNewState)
.launchIn(this)
}
}

fun onLicenseAction() {
viewModelScope.launch {
doEffect(MainViewModelEvent.NavigateToLicense)
onNewEvent(MainViewModelEvent.NavigateToLicense)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class ViewModelTest {
}

@Test
fun onNewState_update_state() = runTest {
fun when_state_is_updated_it_observed() = runTest {
target.state.test {
target.onNewState(0)

Expand All @@ -41,14 +41,14 @@ class ViewModelTest {
}

@Test
fun doEffect_do_emits() = runTest {
target.effect.test {
target.doEffect(0)
fun when_event_happen_it_observed() = runTest {
target.event.test {
target.onNewEvent(0)

assertThat(awaitItem())
.isEqualTo(0)

target.doEffect(42)
target.onNewEvent(42)

assertThat(awaitItem())
.isEqualTo(42)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class MainViewModelTest {

@Test
fun onLicenseAction_emits_NavigateToLicense_event() = runTest {
target.effect.test {
target.event.test {
target.onLicenseAction()

assertThat(awaitItem())
Expand Down

0 comments on commit 99ae17a

Please sign in to comment.