Skip to content

Commit

Permalink
update DialogControl.kt
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex committed May 21, 2022
1 parent baae48f commit 6d4b6fd
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 21 deletions.
2 changes: 1 addition & 1 deletion reactiveviewmodel/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ afterEvaluate {
release(MavenPublication) {
from components.release
groupId = 'com.alexdeww.reactiveviewmodel'
version = '2.4.8'
version = '2.4.9'
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.alexdeww.reactiveviewmodel.core

import android.app.Dialog
import android.widget.CompoundButton
import android.widget.EditText
import android.widget.RatingBar
Expand Down Expand Up @@ -63,10 +64,10 @@ interface RvmViewComponent {
)

fun <T : Any, R : Any> DialogControl<T, R>.bindTo(
createDialog: ActionCreateDialog<T, R>
dialogFactory: DialogFactory<T, R, Dialog>
) = bindTo(
rvmViewComponent = this@RvmViewComponent,
createDialog = createDialog
dialogFactory = dialogFactory
)

fun InputControl.bindTo(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.alexdeww.reactiveviewmodel.widget

import android.app.Dialog
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.Observer
import com.alexdeww.reactiveviewmodel.core.RvmViewComponent
Expand Down Expand Up @@ -71,51 +72,88 @@ fun <T : Any, R : Any> dialogControl(): DialogControl<T, R> = DialogControl()

fun <T : Any> dialogControlWithResult(): DialogControl<T, DialogResult> = DialogControl()

typealias ActionCreateDialog<T, R> = (data: T, dc: DialogControlResult<R>) -> Dialog
fun interface DialogFactory<in T : Any, R : Any, out D : Any> {
fun createDialog(data: T, dc: DialogControlResult<R>): D
}

fun <T : Any, R : Any> DialogControl<T, R>.bindTo(
fun <T : Any, R : Any, D : Any> DialogControl<T, R>.bindToEx(
rvmViewComponent: RvmViewComponent,
createDialog: ActionCreateDialog<T, R>
dialogFactory: DialogFactory<T, R, D>,
dialogLiveDataProvider: (control: DialogControl<T, R>, dialogFactory: DialogFactory<T, R, D>) -> DialogLiveDataMediator<T, R, D>
) {
val liveData = DialogLiveDataMediator(
control = this,
createDialog = createDialog
)
val liveData = dialogLiveDataProvider(this, dialogFactory)
rvmViewComponent.run { liveData.observe { /* empty */ } }
}

private class DialogLiveDataMediator<T : Any, R : Any>(
fun <T : Any, R : Any> DialogControl<T, R>.bindTo(
rvmViewComponent: RvmViewComponent,
dialogFactory: DialogFactory<T, R, Dialog>
) = bindToEx(rvmViewComponent, dialogFactory, ::DialogLiveDataMediatorDialog)

abstract class DialogLiveDataMediator<T : Any, R : Any, D : Any>(
control: DialogControl<T, R>,
createDialog: ActionCreateDialog<T, R>
dialogFactory: DialogFactory<T, R, D>
) : MediatorLiveData<DialogControl.Display<T>>() {

private var dialog: Dialog? = null
private var dialog: D? = null

init {
addSource(control.displayed.liveData) { displayData ->
value = displayData
when (displayData) {
is DialogControl.Display.Displayed -> {
dialog = createDialog(displayData.data, DialogControlResult(control))
dialog?.setOnDismissListener { control.dismiss() }
dialog?.show()
dialog = dialogFactory
.createDialog(
data = displayData.data,
dc = DialogControlResult(control)
).also {
setupOnDismiss(it) { control.dismiss() }
showDialog(it)
}
}
DialogControl.Display.Absent -> closeDialog()
}
}
}

override fun removeObserver(observer: Observer<in DialogControl.Display<T>>) {
final override fun <S : Any?> addSource(source: LiveData<S>, onChanged: Observer<in S>) {
super.addSource(source, onChanged)
}

final override fun removeObserver(observer: Observer<in DialogControl.Display<T>>) {
super.removeObserver(observer)
closeDialog()
}

protected abstract fun setupOnDismiss(dialog: D, dismissAction: () -> Unit)

protected abstract fun showDialog(dialog: D)

protected abstract fun onCloseDialog(dialog: D)

private fun closeDialog() {
dialog?.apply {
setOnDismissListener(null)
dismiss()
}
dialog?.let { onCloseDialog(it) }
dialog = null
}

}

private class DialogLiveDataMediatorDialog<T : Any, R : Any>(
control: DialogControl<T, R>,
dialogFactory: DialogFactory<T, R, Dialog>
) : DialogLiveDataMediator<T, R, Dialog>(control, dialogFactory) {

override fun setupOnDismiss(dialog: Dialog, dismissAction: () -> Unit) {
dialog.setOnDismissListener { dismissAction() }
}

override fun showDialog(dialog: Dialog) {
dialog.show()
}

override fun onCloseDialog(dialog: Dialog) {
dialog.setOnDismissListener(null)
dialog.dismiss()
}

}

0 comments on commit 6d4b6fd

Please sign in to comment.