hybridDeveloper
07/17/2020, 10:01 AMabstract class MviViewModel<I : MviIntent, A : MviResult<VS>, VS : MviViewState>(initialState: VS) : ViewModel() {
private val intentsSubject: PublishSubject<I> = PublishSubject.create()
private val statesObservable: Observable<VS> = intentsSubject
.compose { intents -> intents.publish { shared -> filterIntents(shared) } }
.flatMap { dispatchIntent(it) }
.scan(initialState) { previousState: VS, result: A -> result.reduce(previousState) }
.distinctUntilChanged()
.replay(1)
.autoConnect(0)
abstract fun dispatchIntent(intent: I): Observable<A>
open fun filterIntents(intents: Observable<I>): ObservableSource<I> = intents
fun processIntents(intents: Observable<I>): Disposable {
return intents.subscribe(intentsSubject::onNext)
}
fun states(): Observable<VS> = statesObservable
}
interface MviAnalyticsViewModel {
fun onResume(activity: Activity)
}Fragment
abstract class MviFragment<V : MviView, I : MviIntent, A : MviResult<VS>, VS : MviViewState> : Fragment(), MviView {
private val onStartDisposables = CompositeDisposable()
private val onAttachDisposables = CompositeDisposable()
/**
* This activity should implement the provided MviView generic interface, it will be used by
* the renderer to update the ui.
*/
abstract val view: V
/**
* The ViewModel belonging to the activity
*/
abstract val viewModel: MviViewModel<I, A, VS>
/**
* The Renderer that will update the MviView of this activity
*/
abstract val renderer: MviRenderer<V, VS>
/**
* Push Intents to this
*/
abstract fun onStartIntents(): Observable<I>
abstract fun onStartIntentsFlow(): Flow<I>
/**
* Push Intents to this
*/
open fun onAttachIntents(): Observable<I> = Observable.empty()
open fun onAttachIntentsFlow(): Flow<I> = emptyFlow()
override fun onAttach(context: Context) = super.onAttach(context).also {
AndroidSupportInjection.inject(this)
onAttachDisposables.add(viewModel.processIntents(onAttachIntents()))
}
@ExperimentalCoroutinesApi
override fun onDetach() {
onAttachDisposables.clear()
super.onDetach()
}
override fun onStart() = super.onStart().also {
onStartDisposables.addAll(
viewModel.states()
.observeOn(AndroidSchedulers.mainThread())
.subscribe { renderer.render(view, it) },
viewModel.processIntents(onStartIntents())
)
}
@ExperimentalCoroutinesApi
override fun onStop() {
onStartDisposables.clear()
super.onStop()
}
}