Files
omnivore/apple/OmnivoreKit/Sources/App/Views/Profile/NewsletterEmailsView.swift
2023-07-24 12:11:21 +08:00

125 lines
3.2 KiB
Swift

import Models
import PopupView
import Services
import SwiftUI
import Views
@MainActor final class NewsletterEmailsViewModel: ObservableObject {
@Published var isLoading = false
@Published var emails = [NewsletterEmail]()
func loadEmails(dataService: DataService) async {
isLoading = true
if let objectIDs = try? await dataService.newsletterEmails() {
await dataService.viewContext.perform { [weak self] in
self?.emails = objectIDs.compactMap { dataService.viewContext.object(with: $0) as? NewsletterEmail }
}
}
isLoading = false
}
func createEmail(dataService: DataService) async {
isLoading = true
if let objectID = try? await dataService.createNewsletter() {
await dataService.viewContext.perform { [weak self] in
if let item = dataService.viewContext.object(with: objectID) as? NewsletterEmail {
self?.emails.insert(item, at: 0)
}
}
}
isLoading = false
}
}
struct NewsletterEmailsView: View {
@EnvironmentObject var dataService: DataService
@StateObject var viewModel = NewsletterEmailsViewModel()
@State var showSnackbar = false
@State var snackbarOperation: SnackbarOperation?
func snackbar(message: String) {
snackbarOperation = SnackbarOperation(message: message, undoAction: nil)
showSnackbar = true
}
var body: some View {
Group {
#if os(iOS)
Form {
innerBody
}
#elseif os(macOS)
List {
innerBody
}
.listStyle(InsetListStyle())
#endif
}
.task { await viewModel.loadEmails(dataService: dataService) }
.popup(isPresented: $showSnackbar) {
if let operation = snackbarOperation {
Snackbar(isShowing: $showSnackbar, operation: operation)
} else {
EmptyView()
}
} customize: {
$0
.type(.toast)
.autohideIn(2)
.position(.bottom)
.animation(.spring())
.closeOnTapOutside(true)
}
}
private var innerBody: some View {
Group {
Section(footer: Text(LocalText.newslettersDescription)) {
Button(
action: {
Task { await viewModel.createEmail(dataService: dataService) }
},
label: {
HStack {
Image(systemName: "plus.circle.fill").foregroundColor(.green)
Text(LocalText.createNewEmailMessage)
Spacer()
}
}
)
.disabled(viewModel.isLoading)
}
if !viewModel.emails.isEmpty {
Section(header: Text(LocalText.newsletterEmailsExisting)) {
ForEach(viewModel.emails) { newsletterEmail in
Button(
action: {
#if os(iOS)
UIPasteboard.general.string = newsletterEmail.email
#endif
#if os(macOS)
let pasteBoard = NSPasteboard.general
pasteBoard.clearContents()
pasteBoard.writeObjects([newsletterEmail.unwrappedEmail as NSString])
#endif
snackbar(message: "Email copied")
},
label: { Text(newsletterEmail.unwrappedEmail) }
)
}
}
}
}
.navigationTitle(LocalText.emailsGeneric)
}
}