From e3125626365d85f0524623d6e9219aab7d77bd15 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 18 Dec 2023 12:09:06 +0800 Subject: [PATCH] Separate feeds and newsletters on the subscriptions view --- .../App/Views/Profile/Subscriptions.swift | 97 +++++++++++-------- .../Models/DataModels/Subscription.swift | 9 ++ .../Selections/SubsciptionSelection.swift | 12 +++ 3 files changed, 77 insertions(+), 41 deletions(-) diff --git a/apple/OmnivoreKit/Sources/App/Views/Profile/Subscriptions.swift b/apple/OmnivoreKit/Sources/App/Views/Profile/Subscriptions.swift index 00adc5c4a..b8b194c59 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Profile/Subscriptions.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Profile/Subscriptions.swift @@ -5,8 +5,8 @@ import Views @MainActor final class SubscriptionsViewModel: ObservableObject { @Published var isLoading = true - @Published var subscriptions = [Subscription]() - @Published var popularSubscriptions = [Subscription]() + @Published var feeds = [Subscription]() + @Published var newsletters = [Subscription]() @Published var hasNetworkError = false @Published var subscriptionNameToCancel: String? @@ -14,7 +14,9 @@ import Views isLoading = true do { - subscriptions = try await dataService.subscriptions().filter { $0.status == SubscriptionStatus.active } + let subscriptions = try await dataService.subscriptions().filter { $0.status == SubscriptionStatus.active } + feeds = subscriptions.filter { $0.type == .feed } + newsletters = subscriptions.filter { $0.type == .newsletter } } catch { hasNetworkError = true } @@ -27,10 +29,10 @@ import Views do { try await dataService.deleteSubscription(subscriptionName: subscriptionName) - let index = subscriptions.firstIndex { $0.name == subscriptionName } - if let index = index { - subscriptions.remove(at: index) - } +// let index = subscriptions.firstIndex { $0.name == subscriptionName } +// if let index = index { +// subscriptions.remove(at: index) +// } return true } catch { appLogger.debug("failed to remove subscription") @@ -49,13 +51,6 @@ struct SubscriptionsView: View { Group { if viewModel.isLoading { ProgressView() - .opacity(progressViewOpacity) - .onAppear { - DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(1000)) { - progressViewOpacity = 1 - } - } - .task { await viewModel.loadSubscriptions(dataService: dataService) } } else if viewModel.hasNetworkError { VStack { Text(LocalText.subscriptionsErrorRetrieving).multilineTextAlignment(.center) @@ -65,27 +60,28 @@ struct SubscriptionsView: View { ) .buttonStyle(RoundedRectButtonStyle()) } - } else if viewModel.subscriptions.isEmpty { + } else if viewModel.feeds.isEmpty, viewModel.newsletters.isEmpty { VStack(alignment: .center) { Spacer() Text(LocalText.subscriptionsNone) Spacer() } } else { - Group { - #if os(iOS) - Form { - innerBody - } - #elseif os(macOS) - List { - innerBody - } - .listStyle(InsetListStyle()) - #endif - } + #if os(iOS) + Form { + innerBody + } + #elseif os(macOS) + List { + innerBody + } + .listStyle(InsetListStyle()) + #endif } } + .task { + await viewModel.loadSubscriptions(dataService: dataService) + } .navigationTitle("Subscriptions") #if os(iOS) .navigationBarTitleDisplayMode(.inline) @@ -94,20 +90,39 @@ struct SubscriptionsView: View { private var innerBody: some View { Group { - ForEach(viewModel.subscriptions, id: \.subscriptionID) { subscription in - SubscriptionCell(subscription: subscription) - .swipeActions(edge: .trailing) { - Button( - role: .destructive, - action: { - deleteConfirmationShown = true - viewModel.subscriptionNameToCancel = subscription.name - }, - label: { - Image(systemName: "trash") - } - ) - } + Section("Feeds") { + ForEach(viewModel.feeds, id: \.subscriptionID) { subscription in + SubscriptionCell(subscription: subscription) + .swipeActions(edge: .trailing) { + Button( + role: .destructive, + action: { + deleteConfirmationShown = true + viewModel.subscriptionNameToCancel = subscription.name + }, + label: { + Image(systemName: "trash") + } + ) + } + } + } + Section("Newsletters") { + ForEach(viewModel.newsletters, id: \.subscriptionID) { subscription in + SubscriptionCell(subscription: subscription) + .swipeActions(edge: .trailing) { + Button( + role: .destructive, + action: { + deleteConfirmationShown = true + viewModel.subscriptionNameToCancel = subscription.name + }, + label: { + Image(systemName: "trash") + } + ) + } + } } } .alert("Are you sure you want to cancel this subscription?", isPresented: $deleteConfirmationShown) { diff --git a/apple/OmnivoreKit/Sources/Models/DataModels/Subscription.swift b/apple/OmnivoreKit/Sources/Models/DataModels/Subscription.swift index 784bf8000..78a03fb59 100644 --- a/apple/OmnivoreKit/Sources/Models/DataModels/Subscription.swift +++ b/apple/OmnivoreKit/Sources/Models/DataModels/Subscription.swift @@ -1,10 +1,12 @@ import Foundation +import SwiftGraphQL public struct Subscription { public let createdAt: Date? public let description: String? public let subscriptionID: String public let name: String + public let type: SubscriptionType public let newsletterEmailAddress: String? public let status: SubscriptionStatus public let unsubscribeHttpUrl: String? @@ -18,6 +20,7 @@ public struct Subscription { description: String?, subscriptionID: String, name: String, + type: SubscriptionType, newsletterEmailAddress: String?, status: SubscriptionStatus, unsubscribeHttpUrl: String?, @@ -30,6 +33,7 @@ public struct Subscription { self.description = description self.subscriptionID = subscriptionID self.name = name + self.type = type self.newsletterEmailAddress = newsletterEmailAddress self.status = status self.unsubscribeHttpUrl = unsubscribeHttpUrl @@ -45,3 +49,8 @@ public enum SubscriptionStatus { case deleted case unsubscribed } + +public enum SubscriptionType { + case newsletter + case feed +} diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Selections/SubsciptionSelection.swift b/apple/OmnivoreKit/Sources/Services/DataService/Selections/SubsciptionSelection.swift index 32c2d123a..53944709a 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/Selections/SubsciptionSelection.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/Selections/SubsciptionSelection.swift @@ -9,6 +9,7 @@ let subscriptionSelection = Selection.Subscription { description: try $0.description(), subscriptionID: try $0.id(), name: try $0.name(), + type: try SubscriptionType.from($0.type()), newsletterEmailAddress: try $0.newsletterEmail(), status: try SubscriptionStatus.make(from: $0.status()), unsubscribeHttpUrl: try $0.unsubscribeHttpUrl(), @@ -31,3 +32,14 @@ extension SubscriptionStatus { } } } + +extension SubscriptionType { + static func from(_ other: Enums.SubscriptionType) -> SubscriptionType { + switch other { + case .rss: + return .feed + case .newsletter: + return .newsletter + } + } +}