Skip to content

Instantly share code, notes, and snippets.

@rjrjr
Last active August 5, 2021 21:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rjrjr/c52eb172ed1787dd6b703ad20fe1a121 to your computer and use it in GitHub Desktop.
Save rjrjr/c52eb172ed1787dd6b703ad20fe1a121 to your computer and use it in GitHub Desktop.
Gatekeeper workflow pattern
/**
* In our production code, this typealias is more interesting,
* something like AlertContainerScreen<PanelContainerScreen<R>>
*/
typealias MetaRootRendering<R>: AlertContainerScreen<R>
data class ActivityAndRoot<R> (
val activity: Activity,
val root: R
)
/**
* Receives our root UI and the current Activity as props.
* When rendered, can choose to
* - wrap the given root rendering with modals
* - replace it entirely
* - return `null` to indicate that it doesn't want to interfere
*/
interface GatekeeperWorkflow:
Workflow<ActivityAndRoot<Any>, Nothing, MetaRootRendering<Any>?>
class MetaRootWorkflow<R>(
private val realRootWorkflow: Workflow<R>,
val systemPermissionWorkflow: GatekeeperWorkflow,
val oneTrustWorkflow: GatekeeperWorkflow
): StatelessWorkflow<Activity, Nothing, MetaRootRendering<R>> {
/** In priority order. Dagger injected in real life. */
private val gatekeepers = listOf(
systemPermissionWorkflow, oneTrustWorkflow
)
override fun render(
renderProps: Activity,
context: RenderContext
): RootRendering<GatekeeperScreen> {
// In this sketch we're always running the main UI, whether or
// not we show its rendering.
//
// You might instead want to prevent it from running until
// both Gatekeepers render null, or run some blocking
// Gatekeepers first and another set after.
val root = context.renderChild(realRootWorkflow)
// Note that we are careful always to render all gatekeepers, even if upstream
// ones are blocking downstream via non-null renderings.
val gateOrNull = gatekeepers
.mapNotNull { context.renderChild(it, ActivityAndRoot(renderProps, root) }
.firstOrNull()
return gateOrNull ?: AlertContainerScreen(root)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment