123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- import SwiftUI
- import CoreData
- import FirebaseMessaging
- import UserNotifications
- struct SubscriptionListView: View {
- let tag = "SubscriptionList"
-
- @EnvironmentObject private var store: Store
- @ObservedObject var subscriptionsModel = SubscriptionsObservable()
- @State private var showingAddDialog = false
-
- private var subscriptionManager: SubscriptionManager {
- return SubscriptionManager(store: store)
- }
-
- var body: some View {
- NavigationView {
- if #available(iOS 15.0, *) {
- subscriptionList
- .refreshable {
- subscriptionsModel.subscriptions.forEach { subscription in
- subscriptionManager.poll(subscription)
- }
- }
- } else {
- subscriptionList
- .toolbar {
- ToolbarItem(placement: .navigationBarLeading) {
- Button {
- subscriptionsModel.subscriptions.forEach { subscription in
- subscriptionManager.poll(subscription)
- }
- } label: {
- Image(systemName: "arrow.clockwise")
- }
- }
- }
- }
- }
- .navigationViewStyle(StackNavigationViewStyle())
- }
-
- private var subscriptionList: some View {
- List {
- ForEach(subscriptionsModel.subscriptions) { subscription in
- SubscriptionItemNavView(subscription: subscription)
- }
- }
- .listStyle(PlainListStyle())
- .navigationTitle("Subscribed topics")
- .toolbar {
- ToolbarItem(placement: .navigationBarTrailing) {
- Button {
- self.showingAddDialog = true
- } label: {
- Image(systemName: "plus")
- }
- }
- }
- .overlay(Group {
- if subscriptionsModel.subscriptions.isEmpty {
- VStack {
- Text("It looks like you don't have any subscriptions yet")
- .font(.title2)
- .foregroundColor(.gray)
- .multilineTextAlignment(.center)
- .padding(.bottom)
- if #available(iOS 15.0, *) {
- Text("Click the + to create or subscribe to a topic. Afterwards, you receive notifications on your device when sending messages via PUT or POST.\n\nDetailed instructions are available on [ntfy.sh](https://ntfy.sh) and [in the docs](https://ntfy.sh/docs).")
- .foregroundColor(.gray)
- } else {
- Text("Click the + to create or subscribe to a topic. Afterwards, you receive notifications on your device when sending messages via PUT or POST.\n\nDetailed instructions are available on https://ntfy.sh and https://ntfy.sh/docs")
- .foregroundColor(.gray)
- }
- }
- .padding(40)
- }
- })
- .sheet(isPresented: $showingAddDialog) {
- SubscriptionAddView(isShowing: $showingAddDialog)
- }
- }
- }
- struct SubscriptionItemNavView: View {
- @EnvironmentObject private var store: Store
- @EnvironmentObject private var delegate: AppDelegate
- @ObservedObject var subscription: Subscription
- @State private var unsubscribeAlert = false
-
- private var subscriptionManager: SubscriptionManager {
- return SubscriptionManager(store: store)
- }
-
- var body: some View {
- if #available(iOS 15.0, *) {
- subscriptionRow
- .swipeActions(edge: .trailing) {
- Button(role: .destructive) {
- self.unsubscribeAlert = true
- } label: {
- Label("Delete", systemImage: "trash.circle")
- }
- }
- } else {
- subscriptionRow
- }
- }
-
- private var subscriptionRow: some View {
- ZStack {
- NavigationLink(
- destination: NotificationListView(subscription: subscription),
- tag: subscription.urlString(),
- selection: $delegate.selectedBaseUrl
- ) {
- EmptyView()
- }
- .opacity(0.0)
- .buttonStyle(PlainButtonStyle())
-
- SubscriptionItemRowView(subscription: subscription)
- }
- .alert(isPresented: $unsubscribeAlert) {
- Alert(
- title: Text("Unsubscribe"),
- message: Text("Do you really want to unsubscribe from this topic and delete all of the notifications you received?"),
- primaryButton: .destructive(
- Text("Unsubscribe"),
- action: {
- self.subscriptionManager.unsubscribe(subscription)
- self.unsubscribeAlert = false
- }
- ),
- secondaryButton: .cancel()
- )
- }
- }
- }
- struct SubscriptionItemRowView: View {
- @ObservedObject var subscription: Subscription
-
- var body: some View {
- let totalNotificationCount = subscription.notificationCount()
- VStack(alignment: .leading, spacing: 0) {
- HStack {
- Text(subscription.displayName())
- .font(.headline)
- .bold()
- .lineLimit(1)
- Spacer()
- Text(subscription.lastNotification()?.shortDateTime() ?? "")
- .font(.subheadline)
- .foregroundColor(.gray)
- Image(systemName: "chevron.forward")
- .font(.system(size: 12.0))
- .foregroundColor(.gray)
- }
- Spacer()
- Text("\(totalNotificationCount) notification\(totalNotificationCount != 1 ? "s" : "")")
- .font(.subheadline)
- .foregroundColor(.gray)
- }
- .padding(.all, 4)
- }
- }
- struct SubscriptionListView_Previews: PreviewProvider {
- static var previews: some View {
- let store = Store.preview // Store.previewEmpty
- SubscriptionListView()
- .environment(\.managedObjectContext, store.context)
- .environmentObject(store)
- .environmentObject(AppDelegate())
- }
- }
|