Skip to content

Instantly share code, notes, and snippets.

@gold24park
Created October 7, 2023 09:09
Show Gist options
  • Save gold24park/05b64a44416c802b2b3980805706cf68 to your computer and use it in GitHub Desktop.
Save gold24park/05b64a44416c802b2b3980805706cf68 to your computer and use it in GitHub Desktop.
DialogQueue-2
class DialogQueueImpl(
private val context: Context,
private val lifecycleOwner: LifecycleOwner,
private val fragmentManager: FragmentManager,
): DialogQueue {
private var showingElement: DialogQueueElement? = null
companion object {
private val queue = PriorityQueue<DialogQueueElement>()
const val TAG = "DialogQueue"
}
init {
lifecycleOwner.lifecycle.addObserver(object: LifecycleEventObserver {
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
when (event) {
Lifecycle.Event.ON_RESUME -> flush()
Lifecycle.Event.ON_PAUSE -> {
addFirst(showingElement)
showingElement = null
}
else -> {}
}
}
})
}
private fun addFirst(element: DialogQueueElement?) {
if (element != null) {
queue.offer(element.copy(priority = maxOf(element.priority, DialogQueue.Priority.MEDIUM)))
}
}
override fun add(
element: DialogQueueElement,
) {
queue.offer(element)
flush()
}
private fun flush() {
try {
check(queue.isNotEmpty())
check(showingElement == null) {
"dialog is already showing."
}
check(lifecycleOwner.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
"lifecycle must be resumed."
}
// show dialog
val element = queue.poll()
showingElement = element
val dialog = element.dialogBuilder(context) { // on dismiss
showingElement = null
(fragmentManager.findFragmentByTag(element.tag) as? DialogFragment)?.dismiss()
flush()
}
dialog.show(fragmentManager, element.tag)
} catch (e: IllegalStateException) {
Log.e(TAG, "failed to flush: $e")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment