Skip to content

Instantly share code, notes, and snippets.

@mattmook
Last active July 14, 2021 10:39
Show Gist options
  • Save mattmook/f07ba5f8057a63d392b74b993feadc2a to your computer and use it in GitHub Desktop.
Save mattmook/f07ba5f8057a63d392b74b993feadc2a to your computer and use it in GitHub Desktop.
The state of MVI on Android - MVIKotlin - PostListStoreFactory
internal class PostListStoreFactory(
private val storeFactory: StoreFactory,
private val postRepository: PostRepository,
val stateKeeper: StateKeeper<PostListState>
) {
fun create() = object : Store<PostListIntent, PostListState, NavigationEvent> by storeFactory.create(
name = "PostListStore",
initialState = stateKeeper.consume() ?: PostListState(),
bootstrapper = SimpleBootstrapper(Unit),
executorFactory = ::createExecutorFactory,
reducer = ReducerImpl
) {}
private fun createExecutorFactory() = ExecutorImpl(postRepository)
private class ExecutorImpl(
private val postRepository: PostRepository
) : SuspendExecutor<PostListIntent, Unit, PostListState, List<PostOverview>, NavigationEvent>() {
// Only one Action triggered on create so using Unit
override suspend fun executeAction(action: Unit, getState: () -> PostListState) = loadOverviews()
// Split the intent object back out again
override suspend fun executeIntent(intent: PostListIntent, getState: () -> PostListState) = when (intent) {
is PostListIntent.PostClicked -> postClicked(intent.post)
}
private fun postClicked(post: PostOverview) {
// Triggering a side effect
publish(OpenPostNavigationEvent(post))
}
// Load the overviews
private suspend fun loadOverviews() {
val overviews = withContext(Dispatchers.Default) {
postRepository.getOverviews()
}
// Dispatch the Result
dispatch(overviews)
}
}
private object ReducerImpl : Reducer<PostListState, List<PostOverview>> {
// Combine State and Result
override fun PostListState.reduce(result: List<PostOverview>): PostListState = copy(overviews = result)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment