Warning, /network/kdeconnect-ios/KDE Connect/KDE Connect/Swift Backend/AlertManager.swift is written in an unsupported language. File is not indexed.

0001 //
0002 //  AlertManager.swift
0003 //  KDE Connect
0004 //
0005 //  Created by Stefe on 28/02/2022.
0006 //
0007 
0008 import Foundation
0009 import SwiftUI
0010 import Combine
0011 
0012 struct AlertContent {
0013     let title: LocalizedStringKey
0014     @ViewBuilder let content: () -> Text?
0015     @AlertActionBuilder let buttons: () -> AlertActionBuilder.Buttons?
0016 }
0017 
0018 /**
0019  Manages alerts in-app.
0020  
0021  
0022  You should use it instead of  `.alert()`, whenever you can,
0023  as the default implementation doesn't work with multiple alerts at once.
0024  Because this app uses alerts that come from background service,
0025  we have to manage displaying alerts one after another ourselves.
0026  
0027  An instance of AlertManager can be passed to a view as an @EnvironmentObject.
0028  (See MainTabView.swift)
0029  
0030  To add an alert use ``queueAlert(prioritize:title:content:buttons:)``.
0031  */
0032 class AlertManager: ObservableObject {
0033     var queue: [AlertContent] = []
0034     
0035     @Published var alertPresent: Bool = false
0036     
0037     @Published var currentAlert: AlertContent = AlertContent(
0038         title: "",
0039         content: { Text("") },
0040         buttons: { }
0041     )
0042     
0043     private var cancellables = Set<AnyCancellable>()
0044     
0045     init() {
0046         self.$alertPresent
0047             .receive(on: DispatchQueue.main)
0048             .sink { [weak self] alertPresent in
0049                 guard let self = self else { return }
0050                 if !alertPresent && !self.queue.isEmpty {
0051                     self.currentAlert = self.queue.removeFirst()
0052                     self.alertPresent = true
0053                 }
0054             }
0055             .store(in: &cancellables)
0056     }
0057     
0058     /**
0059      Adds a new alert to the queue and displays it if there isn't one currently on the screen.
0060      
0061      - Parameters:
0062      - prioritize: If true, adds the new alert to the begging of the queue.
0063      Should be used when an alert is shown as a direct result of user interaction.
0064      - title: Title of the alert.
0065      - content: Content (message) of the alert.
0066      - buttons: Buttons for the alert.
0067      */
0068     func queueAlert(
0069         prioritize: Bool = false,
0070         title: LocalizedStringKey,
0071         @ViewBuilder content: @escaping () -> Text?,
0072         @AlertActionBuilder buttons: @escaping () -> AlertActionBuilder.Buttons? = { nil }
0073     ) {
0074         if prioritize {
0075             queue.insert(AlertContent(title: title, content: content, buttons: buttons), at: 0)
0076         } else {
0077             queue.append(AlertContent(title: title, content: content, buttons: buttons))
0078         }
0079         if !alertPresent {
0080             currentAlert = queue.removeFirst()
0081             alertPresent = true
0082         }
0083     }
0084 }