Skip to content

Instantly share code, notes, and snippets.

@darvld
Created April 10, 2022 17:52
Show Gist options
  • Save darvld/f3290bb91ce79b431fe12c2ef06519f8 to your computer and use it in GitHub Desktop.
Save darvld/f3290bb91ce79b431fe12c2ef06519f8 to your computer and use it in GitHub Desktop.
DialogResult helper for Jetpack/Desktop Compose
package io.github.darvld.utils
/**Base class for components representing the result of the user's interaction with a dialog.
*
* To trigger the dialog and obtain the result, use [await].
*
* Note that, since this class provides no UI implementation, [complete] must be manually called from UI code. This is
* typically achieved by showing a dialog when [isAwaiting] is `true`, and using a callback to invoke [complete].*/
interface DialogResult<T> {
/**Whether the dialog is currently pending user interaction.
*
* Composable functions can observe this property to show/hide the corresponding dialog.
*
* @see await*/
val isAwaiting: Boolean
/**Marks this state as [awaiting][isAwaiting] and suspends until a result is obtained.
*
* Subsequent invocations will wait for previous calls to return before triggering the dialog.
*
* @see complete*/
suspend fun await(): T
/** Causes the dialog state to complete with the given [result]. After this invocation, [isAwaiting] will return
* false, and currently suspended [await] calls will return the specified value.
*
* @see await*/
fun complete(result: T): Boolean
}
package io.github.darvld.utils
import androidx.compose.runtime.*
import kotlinx.coroutines.CompletableDeferred
@Composable
fun <T> rememberDialogResult(): DialogResult<T> {
return remember { SnapshotDialogResult() }
}
/**Jetpack Compose implementation of [DialogResult] where [isAwaiting] is observable by the composition.*/
open class SnapshotDialogResult<T> : DialogResult<T> {
private var onResult: CompletableDeferred<T>? by mutableStateOf(null)
override val isAwaiting: Boolean get() = onResult != null
override suspend fun await(): T {
onResult = CompletableDeferred()
val result = onResult!!.await()
onResult = null
return result
}
override fun complete(result: T): Boolean {
return onResult!!.complete(result)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment