Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save AlexanderBollbach/e5e59106d2b3d2a4bb2dc4d50a8bfbbd to your computer and use it in GitHub Desktop.
Save AlexanderBollbach/e5e59106d2b3d2a4bb2dc4d50a8bfbbd to your computer and use it in GitHub Desktop.
signal gathering reducer
extension Reducer {
func gatherSignals<GlobalState, GlobalAction, GlobalEnvironment, Signal>(
signalLocations: [WritableKeyPath<GlobalState, Signal?>],
target: WritableKeyPath<GlobalState, [Signal]>,
startAction: GlobalAction
) -> Reducer<GlobalState, GlobalAction, GlobalEnvironment> {
.init { state, action, environment in
let signals = signalLocations.compactMap { state[keyPath: $0] }
signalLocations.forEach { state[keyPath: $0] = nil}
state[keyPath: target] += signals
return !signals.isEmpty ? .init(value: startAction) : .none
}
}
}
let gatherToastsAndShow = Reducer<AppState, AppAction, AppEnvironment>.combine(
// 'gathers' toasts
Reducer<AppState, AppAction, AppEnvironment>.empty.gatherSignals(
signalLocations: [\AppState.topLevelToast],
target: \AppState.toasts.configs,
startAction: .toast(.trigger)
),
// reads toast configs and asynchronously processes them
toastReducer.pullback(
state: \.toasts,
action: /AppAction.toast,
environment: { _ in () }
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment