From bf94c17ac5feeb471feef9cdff4c80d2922d4237 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Tue, 19 Dec 2023 18:37:43 +0800 Subject: [PATCH] MOre on email views --- .../Views/Profile/NewsletterEmailsView.swift | 98 +++++++++++-------- .../App/Views/Profile/SubscriptionsView.swift | 83 +++++++++------- .../Sources/Views/FormSheetWrapper.swift | 7 -- 3 files changed, 108 insertions(+), 80 deletions(-) diff --git a/apple/OmnivoreKit/Sources/App/Views/Profile/NewsletterEmailsView.swift b/apple/OmnivoreKit/Sources/App/Views/Profile/NewsletterEmailsView.swift index 4f49e17f8..427ad0f69 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Profile/NewsletterEmailsView.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Profile/NewsletterEmailsView.swift @@ -38,18 +38,30 @@ import Views isLoading = false } +// +// func updateEmail(dataService: DataService, subscription: Subscription, folder: String? = nil, fetchContent: Bool? = nil) async { +// operationMessage = "Updating subscription..." +// operationStatus = .isPerforming +// do { +// try await dataService.updateSubscription(subscription.subscriptionID, folder: folder, fetchContent: fetchContent) +// operationMessage = "Subscription updated" +// operationStatus = .success +// } catch { +// operationMessage = "Failed to update subscription" +// operationStatus = .failure +// } +// } } struct NewsletterEmailsView: View { @EnvironmentObject var dataService: DataService @StateObject var viewModel = NewsletterEmailsViewModel() - @State var showAddressCopied = false @State var snackbarOperation: SnackbarOperation? var body: some View { Group { - WindowLink(level: .alert, transition: .move(edge: .bottom), isPresented: $showAddressCopied) { + WindowLink(level: .alert, transition: .move(edge: .bottom), isPresented: $viewModel.showAddressCopied) { MessageToast() } label: { EmptyView() @@ -71,29 +83,30 @@ struct NewsletterEmailsView: View { private var innerBody: some View { Group { - Section(footer: Text(LocalText.newslettersDescription)) { + if !viewModel.emails.isEmpty { + ForEach(viewModel.emails) { email in + Section { + NewsletterEmailRow(viewModel: viewModel, email: email, folderSelection: email.folder) + } + } + } + + Section { + Text(LocalText.newslettersDescription) Button( action: { Task { await viewModel.createEmail(dataService: dataService) } }, label: { - HStack { - Image(systemName: "plus.circle.fill").foregroundColor(.green) + Label(title: { Text(LocalText.createNewEmailMessage) - Spacer() - } + }, icon: { + Image.addLink + }) } ) .disabled(viewModel.isLoading) } - - if !viewModel.emails.isEmpty { - Section(header: Text(LocalText.newsletterEmailsExisting)) { - ForEach(viewModel.emails) { email in - NewsletterEmailRow(viewModel: viewModel, email: email, folderSelection: email.folder) - } - } - } } .navigationTitle(LocalText.emailsGeneric) } @@ -106,40 +119,47 @@ struct NewsletterEmailRow: View { var body: some View { VStack { - Button( - action: { - #if os(iOS) - UIPasteboard.general.string = email.email - #endif + HStack { + Text(email.unwrappedEmail) + Spacer() - #if os(macOS) - let pasteBoard = NSPasteboard.general - pasteBoard.clearContents() - pasteBoard.writeObjects([newsletterEmail.unwrappedEmail as NSString]) - #endif + Button( + action: { + #if os(iOS) + UIPasteboard.general.string = email.email + #endif - viewModel.showAddressCopied = true - DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(2000)) { - viewModel.showAddressCopied = false + #if os(macOS) + let pasteBoard = NSPasteboard.general + pasteBoard.clearContents() + pasteBoard.writeObjects([newsletterEmail.unwrappedEmail as NSString]) + #endif + + viewModel.showAddressCopied = true + DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(2000)) { + viewModel.showAddressCopied = false + } + }, + label: { + Text("Copy") } - }, - label: { Text(email.unwrappedEmail).font(Font.appFootnote) } - ) - Divider() - Picker("Destination Folder", selection: $folderSelection) { - Text("Inbox").tag("inbox") - Text("Following").tag("following") + ) } - .pickerStyle(MenuPickerStyle()) - .onChange(of: folderSelection) { _ in +// Divider() +// Picker("Destination Folder", selection: $folderSelection) { +// Text("Inbox").tag("inbox") +// Text("Following").tag("following") +// } +// .pickerStyle(MenuPickerStyle()) +// .onChange(of: folderSelection) { newValue in // Task { // viewModel.showOperationToast = true -// await viewModel.updateSubscription(dataService: dataService, subscription: subscription, folder: newValue) +// await viewModel.updateEmail(dataService: dataService, email: email, folder: newValue) // DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(1500)) { // viewModel.showOperationToast = false // } // } - } +// } } } } diff --git a/apple/OmnivoreKit/Sources/App/Views/Profile/SubscriptionsView.swift b/apple/OmnivoreKit/Sources/App/Views/Profile/SubscriptionsView.swift index d40547fe6..de092a50c 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Profile/SubscriptionsView.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Profile/SubscriptionsView.swift @@ -129,7 +129,6 @@ struct SubscriptionsView: View { @State private var showDeleteCompleted = false @State private var showAddFeedView = false - @State private var showSubscriptionsSheet = false var body: some View { Group { @@ -191,28 +190,9 @@ struct SubscriptionsView: View { LibraryAddFeedView(dismiss: { showAddFeedView = false }, toastOperationHandler: handler) + .navigationViewStyle(.stack) } - } - .formSheet(isPresented: $showSubscriptionsSheet) { - if let presentingSubscription = viewModel.presentingSubscription { - SubscriptionSettingsView( - subscription: presentingSubscription, - viewModel: viewModel, - dataService: dataService, - prefetchContent: presentingSubscription.fetchContent, - folderSelection: presentingSubscription.folder, - dismiss: { showSubscriptionsSheet = false }, - unsubscribe: { subscription in - showSubscriptionsSheet = false - - viewModel.operationStatus = .isPerforming - viewModel.showOperationToast = true - Task { - await viewModel.cancelSubscription(dataService: dataService, subscription: subscription) - } - } - ) - } + .navigationViewStyle(.stack) } .task { await viewModel.loadSubscriptions(dataService: dataService) @@ -242,24 +222,56 @@ struct SubscriptionsView: View { .padding() } else { ForEach(viewModel.feeds, id: \.subscriptionID) { subscription in - Button(action: { - viewModel.presentingSubscription = subscription - showSubscriptionsSheet = true - }, label: { + PresentationLink(transition: UIDevice.isIPad ? .popover : .sheet(detents: [.medium])) { + SubscriptionSettingsView( + subscription: subscription, + viewModel: viewModel, + dataService: dataService, + prefetchContent: subscription.fetchContent, + folderSelection: subscription.folder, + unsubscribe: { _ in + viewModel.operationStatus = .isPerforming + viewModel.showOperationToast = true + Task { + await viewModel.cancelSubscription(dataService: dataService, subscription: subscription) + } + } + ) + } label: { SubscriptionCell(subscription: subscription) - }) + } } + Button(action: { showAddFeedView = true }, label: { + Label(title: { + Text("Add a feed") + }, icon: { + Image.addLink + }) + }) } } + if viewModel.newsletters.count > 0, !viewModel.isLoading { Section("Newsletters") { ForEach(viewModel.newsletters, id: \.subscriptionID) { subscription in - Button(action: { - viewModel.presentingSubscription = subscription - showSubscriptionsSheet = true - }, label: { + PresentationLink(transition: UIDevice.isIPad ? .popover : .sheet(detents: [.medium])) { + SubscriptionSettingsView( + subscription: subscription, + viewModel: viewModel, + dataService: dataService, + prefetchContent: subscription.fetchContent, + folderSelection: subscription.folder, + unsubscribe: { _ in + viewModel.operationStatus = .isPerforming + viewModel.showOperationToast = true + Task { + await viewModel.cancelSubscription(dataService: dataService, subscription: subscription) + } + } + ) + } label: { SubscriptionCell(subscription: subscription) - }) + } } } } @@ -344,9 +356,11 @@ struct SubscriptionSettingsView: View { @State var showDeleteCompleted = false @State var folderSelection: String = "" - let dismiss: () -> Void + // let dismiss: () -> Void let unsubscribe: (_: Subscription) -> Void + @Environment(\.dismiss) private var dismiss + var body: some View { VStack { SubscriptionRow(subscription: subscription, useImageSpacer: false, trailingButton: { @@ -407,9 +421,10 @@ struct SubscriptionSettingsView: View { .frame(maxWidth: .infinity) .buttonStyle(RoundedRectButtonStyle(color: Color.red, textColor: Color.white)) } - .frame(minWidth: 200, minHeight: 200) + .frame(width: UIDevice.isIPad ? 400 : nil, height: UIDevice.isIPad ? 300 : nil) .alert("Are you sure you want to cancel this subscription?", isPresented: $deleteConfirmationShown) { Button("Yes", role: .destructive) { + dismiss() unsubscribe(subscription) } Button("No", role: .cancel) { diff --git a/apple/OmnivoreKit/Sources/Views/FormSheetWrapper.swift b/apple/OmnivoreKit/Sources/Views/FormSheetWrapper.swift index b20503955..090528d57 100644 --- a/apple/OmnivoreKit/Sources/Views/FormSheetWrapper.swift +++ b/apple/OmnivoreKit/Sources/Views/FormSheetWrapper.swift @@ -1,10 +1,3 @@ -// -// FormSheet.swift -// -// -// Created by Jackson Harper on 1/29/22. -// - import SwiftUI #if os(iOS)