You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
PadelClub/PadelClub/Utils/ContactManager.swift

208 lines
8.3 KiB

//
// ContactManager.swift
// Padel Tournament
//
// Created by Razmig Sarkissian on 19/09/2023.
//
import Foundation
import SwiftUI
import MessageUI
import LeStorage
enum ContactManagerError: LocalizedError {
case mailFailed
case mailNotSent //no network no error
case messageFailed
case messageNotSent //no network no error
}
enum ContactType: Identifiable {
case mail(date: Date?, recipients: [String]?, bccRecipients: [String]?, body: String?, subject: String?, tournamentBuild: TournamentBuild?)
case message(date: Date?, recipients: [String]?, body: String?, tournamentBuild: TournamentBuild?)
var id: Int {
switch self {
case .message: return 0
case .mail: return 1
}
}
}
extension ContactType {
static let defaultCustomMessage: String =
"""
Il est conseillé de vous présenter 10 minutes avant de jouer.\n\nMerci de me confirmer votre présence avec votre nom et de prévenir votre partenaire.
"""
static let defaultAvailablePaymentMethods: String = "Règlement possible par chèque ou espèces."
static func callingCustomMessage(source: String? = nil, tournament: Tournament?, startDate: Date?, roundLabel: String) -> String {
let tournamentCustomMessage = source ?? DataStore.shared.user.summonsMessageBody ?? defaultCustomMessage
let clubName = tournament?.clubName ?? ""
var text = tournamentCustomMessage
let date = startDate ?? tournament?.startDate ?? Date()
if let tournament {
text = text.replacingOccurrences(of: "#titre", with: tournament.tournamentTitle(.short))
text = text.replacingOccurrences(of: "#prix", with: tournament.entryFeeMessage)
}
text = text.replacingOccurrences(of: "#club", with: clubName)
text = text.replacingOccurrences(of: "#manche", with: roundLabel.lowercased())
text = text.replacingOccurrences(of: "#jour", with: "\(date.formatted(Date.FormatStyle().weekday(.wide).day().month(.wide)))")
text = text.replacingOccurrences(of: "#horaire", with: "\(date.formatted(Date.FormatStyle().hour().minute()))")
let signature = DataStore.shared.user.summonsMessageSignature ?? DataStore.shared.user.defaultSignature()
text = text.replacingOccurrences(of: "#signature", with: signature)
return text
}
static func callingMessage(tournament: Tournament?, startDate: Date?, roundLabel: String, matchFormat: MatchFormat?, reSummon: Bool = false) -> String {
let useFullCustomMessage = DataStore.shared.user.summonsUseFullCustomMessage
if useFullCustomMessage {
return callingCustomMessage(tournament: tournament, startDate: startDate, roundLabel: roundLabel)
}
let date = startDate ?? tournament?.startDate ?? Date()
let clubName = tournament?.clubName ?? ""
let message = DataStore.shared.user.summonsMessageBody ?? defaultCustomMessage
let signature = DataStore.shared.user.summonsMessageSignature ?? DataStore.shared.user.defaultSignature()
let localizedCalled = "convoqué" + (tournament?.tournamentCategory == .women ? "e" : "") + "s"
var entryFeeMessage: String? {
(DataStore.shared.user.summonsDisplayEntryFee) ? tournament?.entryFeeMessage : nil
}
var computedMessage: String {
[entryFeeMessage, message].compacted().map { $0.trimmedMultiline }.joined(separator: "\n\n")
}
let intro = reSummon ? "Suite à des forfaits, vous êtes finalement" : "Vous êtes"
if let tournament {
return "Bonjour,\n\n\(intro) \(localizedCalled) pour jouer en \(roundLabel.lowercased()) du \(tournament.tournamentTitle(.short)) au \(clubName) le \(date.formatted(Date.FormatStyle().weekday(.wide).day().month(.wide))) à \(date.formatted(Date.FormatStyle().hour().minute())).\n\n" + computedMessage + "\n\n\(signature)"
} else {
return "Bonjour,\n\n\(intro) \(localizedCalled) \(roundLabel) au \(clubName) le \(date.formatted(Date.FormatStyle().weekday(.wide).day().month(.wide))) à \(date.formatted(Date.FormatStyle().hour().minute())).\n\nMerci de confirmer en répondant à ce message et de prévenir votre partenaire !\n\n\(signature)"
}
}
}
struct MessageComposeView: UIViewControllerRepresentable {
typealias Completion = (_ result: MessageComposeResult) -> Void
static var canSendText: Bool { MFMessageComposeViewController.canSendText() }
let recipients: [String]?
let body: String?
let completion: Completion?
func makeUIViewController(context: Context) -> UIViewController {
guard Self.canSendText else {
let errorView = ContentUnavailableView("Aucun compte de messagerie", systemImage: "xmark", description: Text("Aucun compte de messagerie n'est configuré sur cet appareil."))
return UIHostingController(rootView: errorView)
}
let controller = MFMessageComposeViewController()
controller.messageComposeDelegate = context.coordinator
controller.recipients = recipients
controller.body = body
return controller
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
func makeCoordinator() -> Coordinator {
Coordinator(completion: self.completion)
}
class Coordinator: NSObject, MFMessageComposeViewControllerDelegate {
private let completion: Completion?
public init(completion: Completion?) {
self.completion = completion
}
public func messageComposeViewController(_ controller: MFMessageComposeViewController, didFinishWith result: MessageComposeResult) {
controller.dismiss(animated: true, completion: {
self.completion?(result)
})
}
}
}
struct MailComposeView: UIViewControllerRepresentable {
typealias Completion = (_ result: MFMailComposeResult) -> Void
static var canSendMail: Bool {
if let mailURL = URL(string: "mailto:?to=jap@padelclub.com") {
let mailConfigured = UIApplication.shared.canOpenURL(mailURL)
return mailConfigured && MFMailComposeViewController.canSendMail()
} else {
return MFMailComposeViewController.canSendMail()
}
}
let recipients: [String]?
let bccRecipients: [String]?
let body: String?
let subject: String?
var attachmentURL: URL?
let completion: Completion?
func makeUIViewController(context: Context) -> UIViewController {
guard Self.canSendMail else {
let errorView = ContentUnavailableView("Aucun compte mail", systemImage: "xmark", description: Text("Aucun compte mail n'est configuré sur cet appareil."))
return UIHostingController(rootView: errorView)
}
let controller = MFMailComposeViewController()
controller.mailComposeDelegate = context.coordinator
controller.setToRecipients(recipients)
controller.setBccRecipients(bccRecipients)
if let attachmentURL {
do {
let attachmentData = try Data(contentsOf: attachmentURL)
controller.addAttachmentData(attachmentData, mimeType: "application/zip", fileName: "backup.zip")
} catch {
print("Could not attach file: \(error)")
}
}
if let body {
controller.setMessageBody(body, isHTML: false)
}
if let subject {
controller.setSubject(subject)
}
return controller
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}
func makeCoordinator() -> Coordinator {
Coordinator(completion: self.completion)
}
class Coordinator: NSObject, MFMailComposeViewControllerDelegate {
private let completion: Completion?
public init(completion: Completion?) {
self.completion = completion
}
public func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
controller.dismiss(animated: true, completion: {
self.completion?(result)
})
}
}
}