diff --git a/docs/GETTING_STARTED.md b/docs/GETTING_STARTED.md index 99f2b70..3f65783 100644 --- a/docs/GETTING_STARTED.md +++ b/docs/GETTING_STARTED.md @@ -54,4 +54,6 @@ Note: these requirements are strictly based off of my development on this app. T - https://stackoverflow.com/a/41783666/1440785 - https://stackoverflow.com/questions/47374903/viewing-core-data-data-from-your-app-on-a-device - https://debashishdas3100.medium.com/save-push-notifications-to-coredata-userdefaults-ios-swift-5-ea074390b57 -- https://cocoacasts.com/cocoa-fundamentals-how-to-access-builds-settings-in-swift \ No newline at end of file +- https://cocoacasts.com/cocoa-fundamentals-how-to-access-builds-settings-in-swifti +- https://www.hackingwithswift.com/articles/216/complete-guide-to-navigationview-in-swiftui +- https://stackoverflow.com/a/70731861/1440785 diff --git a/ntfy/App/AppDelegate.swift b/ntfy/App/AppDelegate.swift index 94b90ae..c5688cc 100644 --- a/ntfy/App/AppDelegate.swift +++ b/ntfy/App/AppDelegate.swift @@ -5,9 +5,12 @@ import Firebase import FirebaseCore import CoreData -class AppDelegate: UIResponder, UIApplicationDelegate { +class AppDelegate: UIResponder, UIApplicationDelegate, ObservableObject { let tag = "AppDelegate" + // Implements navigation from notifications, see https://stackoverflow.com/a/70731861/1440785 + @Published var selectedBaseUrl: String? = nil + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { Log.d(tag, "Launching AppDelegate") @@ -61,7 +64,11 @@ extension AppDelegate: UNUserNotificationCenterDelegate { ) { let userInfo = response.notification.request.content.userInfo Log.d(tag, "Notification received via userNotificationCenter(didReceive)", userInfo) - // TODO: This should navigate to the detail view + + if let topic = userInfo["topic"] as? String { + selectedBaseUrl = topicUrl(baseUrl: Config.appBaseUrl, topic: topic) + } + completionHandler() } } diff --git a/ntfy/App/AppMain.swift b/ntfy/App/AppMain.swift index 20f7139..0151d0a 100644 --- a/ntfy/App/AppMain.swift +++ b/ntfy/App/AppMain.swift @@ -34,6 +34,7 @@ struct AppMain: App { ContentView() .environment(\.managedObjectContext, store.context) .environmentObject(store) + .environmentObject(delegate) .onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in // Use this hook instead of applicationDidBecomeActive, see https://stackoverflow.com/a/68888509/1440785 // That post also explains how to start SwiftUI from AppDelegate if that's ever needed. diff --git a/ntfy/Views/NotificationListView.swift b/ntfy/Views/NotificationListView.swift index 32cbccb..d4f77ef 100644 --- a/ntfy/Views/NotificationListView.swift +++ b/ntfy/Views/NotificationListView.swift @@ -7,7 +7,7 @@ enum ActiveAlert { struct NotificationListView: View { private let tag = "NotificationListView" - @Environment(\.presentationMode) var presentationMode + @EnvironmentObject private var delegate: AppDelegate @EnvironmentObject private var store: Store @ObservedObject var subscription: Subscription @@ -31,8 +31,22 @@ struct NotificationListView: View { .listStyle(PlainListStyle()) .navigationBarTitleDisplayMode(.inline) .environment(\.editMode, self.$editMode) - .navigationBarBackButtonHidden(self.editMode == .active) + .navigationBarBackButtonHidden(true) .toolbar { + ToolbarItem(placement: .navigationBarLeading) { + if (self.editMode != .active) { + Button(action: { + // iOS bug (?): We create a custom back button, because when we return using the original + // back button, and the navigation is popped that way, the row stays highlighted for a long + // time, which is weird and feels wrong. This avoids that behavior. + + self.delegate.selectedBaseUrl = nil + }){ + Image(systemName: "chevron.left") + } + .padding([.top, .bottom, .trailing], 20) + } + } ToolbarItem(placement: .principal) { Text(subscription.displayName()).font(.headline) } @@ -59,6 +73,7 @@ struct NotificationListView: View { } } label: { Image(systemName: "ellipsis.circle") + .padding([.top, .bottom, .leading], 20) } } } @@ -161,7 +176,7 @@ struct NotificationListView: View { DispatchQueue.global(qos: .background).async { subscriptionManager.unsubscribe(subscription) } - presentationMode.wrappedValue.dismiss() + delegate.selectedBaseUrl = nil } private func deleteAll() { diff --git a/ntfy/Views/SubscriptionListView.swift b/ntfy/Views/SubscriptionListView.swift index a461ff2..2e5457b 100644 --- a/ntfy/Views/SubscriptionListView.swift +++ b/ntfy/Views/SubscriptionListView.swift @@ -55,6 +55,7 @@ struct SubscriptionListView: View { struct SubscriptionItemNavView: View { @EnvironmentObject private var store: Store + @EnvironmentObject private var delegate: AppDelegate @ObservedObject var subscription: Subscription @State private var unsubscribeAlert = false @@ -64,7 +65,11 @@ struct SubscriptionItemNavView: View { var body: some View { ZStack { - NavigationLink(destination: NotificationListView(subscription: subscription)) { + NavigationLink( + destination: NotificationListView(subscription: subscription), + tag: subscription.urlString(), + selection: $delegate.selectedBaseUrl + ) { EmptyView() } .opacity(0.0)