Skip to content

Instantly share code, notes, and snippets.

@maximkrouk
Last active July 5, 2020 12:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maximkrouk/6110c4dade30d85218c11ccf9a22ba92 to your computer and use it in GitHub Desktop.
Save maximkrouk/6110c4dade30d85218c11ccf9a22ba92 to your computer and use it in GitHub Desktop.
import SwiftUI
import CombineFeedback
import CombineFeedbackUI
protocol Module: Loggable, Identifiable, StatefulProtocol, EventfulProtocol
where State: Identifiable, ID == State.ID, State.ID == UUID, Store.State == State, Store.Event == Event {
associatedtype Store: CFUIStoreProtocol
associatedtype Event
associatedtype ContentView: ContextualView
var store: Store { get }
init(store: Store)
}
extension Module {
var id: ID { store.state.id }
}
protocol ContextualView: View {
associatedtype _Context: CFUIContextProtocol
var context: _Context { get }
init(context: _Context)
}
import Combine
import CombineFeedback
import CombineFeedbackUI
typealias _Store<State, Event> = CombineFeedbackUI.Store<State, Event>
extension _Store {
static func userInput(_ input: AnyPublisher<Event, Never>) -> Feedback<State, Event> {
.middleware { _ in input }
}
func send(events: Event...) { send(events: events) }
func send(events: [Event]) { events.forEach(send) }
}
import SwiftUI
import CombineFeedback
import CombineFeedbackUI
protocol StatefulProtocol {
associatedtype State
}
protocol EventfulProtocol {
associatedtype State
}
protocol CFUIStoreProtocol: StatefulProtocol, EventfulProtocol {
associatedtype Event
var state: State { get }
func send(event: Event)
func mutate<V>(keyPath: WritableKeyPath<State, V>, value: V)
}
protocol CFUIContextProtocol: ObservableObject, StatefulProtocol, EventfulProtocol {}
extension CombineFeedbackUI.Store: CFUIStoreProtocol {}
extension Context: CFUIContextProtocol {}
import SwiftUI
import CombineFeedbackUI
extension View where Self: Identifiable, Self.ID == UUID {
func onDismiss(perform action: (() -> Void)?) -> some View {
Router.shared.onDismiss(of: id, perform: action)
return self
}
}
private class Router {
fileprivate static let shared: Router = .init()
private var handlers: [UUID: (() -> Void)?] = [:]
fileprivate func dismiss(_ id: UUID) {
let handler = handlers[id]
handlers[id] = nil
handler??()
}
fileprivate func onDismiss(of id: UUID, perform action: (() -> Void)?) {
handlers[id] = action
}
}
extension Context where State: Identifiable, State.ID == UUID {
func dismiss() { Router.shared.dismiss(self.id) }
}
@maximkrouk
Copy link
Author

maximkrouk commented Jun 29, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment