| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- extension View {
- public func alert(
- _ title: String,
- isPresented: Binding<Bool>,
- @AlertActionsBuilder actions: () -> [AlertAction]
- ) -> some View {
- AlertModifierView(
- child: self,
- title: title,
- isPresented: isPresented,
- actions: actions()
- )
- }
- public func alert(
- _ title: Binding<String?>,
- @AlertActionsBuilder actions: () -> [AlertAction]
- ) -> some View {
- AlertModifierView(
- child: self,
- title: title.wrappedValue ?? "",
- isPresented: Binding {
- title.wrappedValue != nil
- } set: { newValue in
- if !newValue {
- title.wrappedValue = nil
- }
- },
- actions: actions()
- )
- }
- }
- struct AlertModifierView<Child: View>: TypeSafeView {
- typealias Children = AlertModifierViewChildren<Child>
- var body = EmptyView()
- var child: Child
- var title: String
- var isPresented: Binding<Bool>
- var actions: [AlertAction]
- func children<Backend: BaseAppBackend>(
- backend: Backend,
- snapshots: [ViewGraphSnapshotter.NodeSnapshot]?,
- environment: EnvironmentValues
- ) -> Children {
- AlertModifierViewChildren(
- childNode: AnyViewGraphNode(
- ViewGraphNode(
- for: child,
- backend: backend,
- environment: environment
- )
- ),
- alert: nil
- )
- }
- func asWidget<Backend: BaseAppBackend>(
- _ children: Children,
- backend: Backend
- ) -> Backend.Widget {
- children.childNode.widget.into()
- }
- func computeLayout<Backend: BaseAppBackend>(
- _ widget: Backend.Widget,
- children: Children,
- proposedSize: ProposedViewSize,
- environment: EnvironmentValues,
- backend: Backend
- ) -> ViewLayoutResult {
- children.childNode.computeLayout(
- with: child,
- proposedSize: proposedSize,
- environment: environment
- )
- }
- func commit<Backend: BaseAppBackend>(
- _: Backend.Widget,
- children: AlertModifierViewChildren<Child>,
- layout: ViewLayoutResult,
- environment: EnvironmentValues,
- backend: Backend
- ) {
- func castBackend_inner<NewBackend: BaseAppBackend & BackendFeatures.Alerts>(_ backend: NewBackend) {
- _ = children.childNode.commit()
- if isPresented.wrappedValue && children.alert == nil {
- let alert = backend.createAlert()
- backend.updateAlert(
- alert,
- title: title,
- actionLabels: actions.map(\.label),
- environment: environment
- )
- backend.showAlert(
- alert,
- window: .some(environment.window! as! NewBackend.Window)
- ) { responseId in
- children.alert = nil
- isPresented.wrappedValue = false
- actions[responseId].action()
- }
- children.alert = alert
- } else if isPresented.wrappedValue == false && children.alert != nil {
- backend.dismissAlert(
- children.alert as! NewBackend.Alert,
- window: .some(environment.window! as! NewBackend.Window)
- )
- children.alert = nil
- }
- }
- guard let castedBackend = backend as? any (BaseAppBackend & BackendFeatures.Alerts) else {
- fatalError("Backend does not implement BackendFeatures.Alerts")
- }
- castBackend_inner(castedBackend)
- }
- }
- class AlertModifierViewChildren<Child: View>: ViewGraphNodeChildren {
- var childNode: AnyViewGraphNode<Child>
- var alert: Any?
- var widgets: [AnyWidget] {
- [childNode.widget]
- }
- var erasedNodes: [ErasedViewGraphNode] {
- [ErasedViewGraphNode(wrapping: childNode)]
- }
- init(
- childNode: AnyViewGraphNode<Child>,
- alert: Any?
- ) {
- self.childNode = childNode
- self.alert = alert
- }
- }
|