Skip to content

Instantly share code, notes, and snippets.

@eungju
Last active May 10, 2016 16:44
Show Gist options
  • Save eungju/7be75a83b2b1b839b3f7d8ebf18d9d65 to your computer and use it in GitHub Desktop.
Save eungju/7be75a83b2b1b839b3f7d8ebf18d9d65 to your computer and use it in GitHub Desktop.
MVP+RxJava
class LocationAgreementAgree(scheduling: RxScheduling,
api: Api,
session: Session) : LocationAgreementSubmit(scheduling, api, session, true) {
private val disuseChecked = BehaviorRelay.create<Boolean>(false)
private val termsOfUseChecked = BehaviorRelay.create<Boolean>(false)
private val ageChecked = BehaviorRelay.create<Boolean>(false)
override val positiveEnabled = Observable.combineLatest(disuseChecked, termsOfUseChecked, ageChecked, { a, b, c -> a && b && c })
fun disuseChecked(): Observable<Boolean> = disuseChecked
fun termsOfUseChecked(): Observable<Boolean> = termsOfUseChecked
fun ageChecked(): Observable<Boolean> = ageChecked
fun onDisuseCheck(): Action1<Boolean> = disuseChecked
fun onTermsOfUseCheck(): Action1<Boolean> = termsOfUseChecked
fun onAgeCheck(): Action1<Boolean> = ageChecked
fun initialize() {
disuseChecked.call(false)
termsOfUseChecked.call(false)
ageChecked.call(false)
}
}
abstract class LocationAgreementSubmit(scheduling: RxScheduling,
api: Api,
session: Session,
agree: Boolean) : RxViewModel() {
private class Submit(val agree: Boolean)
protected abstract val positiveEnabled: Observable<Boolean>
private val positive = PublishRelay.create<Unit>()
private val negative = PublishRelay.create<Unit>()
private val submitError = PublishRelay.create<Unit>()
//lazy delegate를 쓰지 않으면 positiveEnabled가 null이다.
private val submitSuccess by lazy {
positive.withLatestFrom(positiveEnabled, { a, b -> b })
.filter { it }
.map { Submit(agree) }
.concatMap { request ->
api.putPolicies(Policy.getLocationAgreed(request.agree))
.compose(scheduling.ioThenUi_())
.onErrorResumeNext {
submitError.call(Unit)
Observable.empty()
}
.map { ApiCall(request, it) }
}
.doOnNext { call ->
session.isLocationAgreed = call.request.agree
}
.map { Unit }
}
fun positiveEnabled(): Observable<Boolean> = positiveEnabled
fun submitSuccess(): Observable<Unit> = submitSuccess
fun submitError(): Observable<Unit> = submitError
fun close(): Observable<Unit> = negative
fun onPositive(): Action1<Unit> = positive
fun onNegative(): Action1<Unit> = negative
}
class LocationUseAgree(scheduling: RxScheduling, api: Api, session: Session) : LocationUseToggle<LocationUseAgree.View>(scheduling, api, session) {
interface View : LocationUseToggle.View {
fun agreeEnabled(enabled: Boolean)
fun setDisuseCheck(checked: Boolean)
fun setTermsOfUseCheck(checked: Boolean)
fun setAgeCheck(checked: Boolean)
}
var disuseChecked: Boolean = false
var termsOfUseChecked: Boolean = false
var ageChecked: Boolean = false
var agreeEnabled: Boolean = false
fun initialize() {
disuseChecked = false
termsOfUseChecked = false
ageChecked = false
agreeEnabled = true
view.setDisuseCheck(disuseChecked)
view.setTermsOfUseCheck(termsOfUseChecked)
view.setAgeCheck(ageChecked)
}
fun disuseCheck() {
disuseChecked = !disuseChecked
enableOrDisableAgree()
}
fun termsOfUseCheck() {
termsOfUseChecked = !termsOfUseChecked
enableOrDisableAgree()
}
fun ageCheck() {
ageChecked = !ageChecked
enableOrDisableAgree()
}
fun agree() {
if (!disuseChecked || !termsOfUseChecked || !ageChecked) {
return
}
saveRelay.call(LocationUseToggle.Save(true))
}
private fun enableOrDisableAgree() {
if (disuseChecked && termsOfUseChecked && ageChecked) {
agreeEnabled = true
view.agreeEnabled(agreeEnabled)
} else if (agreeEnabled) {
agreeEnabled = false
view.agreeEnabled(agreeEnabled)
}
}
}
abstract class LocationUseToggle<ViewType : LocationUseToggle.View>(protected val scheduling: RxScheduling,
protected val api: Api,
protected val session: Session) : BasePresenter<ViewType>() {
interface View : PassiveView {
fun close()
fun showSaveError()
}
class Save(val agree: Boolean)
protected val saveRelay = PublishRelay.create<Save>()
override fun attach(view: ViewType) {
super.attach(view)
subscriptions.add(saveRelay
.distinctUntilChanged { it.agree }
.concatMap { request ->
api.putPolicies(Policy.getLocationAgreed(request.agree))
.compose(scheduling.ioThenUi_())
.doOnError { throwable ->
view.showSaveError()
}
.onErrorResumeNext(Observable.empty())
.map { ApiCall(request, it) }
}
.subscribe { call ->
session.isLocationAgreed = call.request.agree
view.close()
})
}
open fun cancel() {
view.close()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment