diff --git a/Nos.xcodeproj/project.pbxproj b/Nos.xcodeproj/project.pbxproj index 3a1ed9941..37bdd78e3 100644 --- a/Nos.xcodeproj/project.pbxproj +++ b/Nos.xcodeproj/project.pbxproj @@ -262,6 +262,7 @@ C97A1C8C29E45B4E009D9E8D /* RawEventController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C97A1C8A29E45B4E009D9E8D /* RawEventController.swift */; }; C97A1C8E29E58EC7009D9E8D /* NSManagedObjectContext+Nos.swift in Sources */ = {isa = PBXBuildFile; fileRef = C97A1C8D29E58EC7009D9E8D /* NSManagedObjectContext+Nos.swift */; }; C97A1C8F29E58EC7009D9E8D /* NSManagedObjectContext+Nos.swift in Sources */ = {isa = PBXBuildFile; fileRef = C97A1C8D29E58EC7009D9E8D /* NSManagedObjectContext+Nos.swift */; }; + C97B288A2C10B07100DC1FC0 /* NosNavigationStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = C97B28892C10B07100DC1FC0 /* NosNavigationStack.swift */; }; C981E2DB2AC6088900FBF4F6 /* UNSVerifyCodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C981E2DA2AC6088900FBF4F6 /* UNSVerifyCodeView.swift */; }; C981E2DD2AC610D600FBF4F6 /* UNSStepImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C981E2DC2AC610D600FBF4F6 /* UNSStepImage.swift */; }; C98298332ADD7F9A0096C5B5 /* DeepLinkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C98298322ADD7F9A0096C5B5 /* DeepLinkService.swift */; }; @@ -687,6 +688,7 @@ C97A1C8729E45B3C009D9E8D /* RawEventView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RawEventView.swift; sourceTree = ""; }; C97A1C8A29E45B4E009D9E8D /* RawEventController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RawEventController.swift; sourceTree = ""; }; C97A1C8D29E58EC7009D9E8D /* NSManagedObjectContext+Nos.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+Nos.swift"; sourceTree = ""; }; + C97B28892C10B07100DC1FC0 /* NosNavigationStack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NosNavigationStack.swift; sourceTree = ""; }; C981E2DA2AC6088900FBF4F6 /* UNSVerifyCodeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UNSVerifyCodeView.swift; sourceTree = ""; }; C981E2DC2AC610D600FBF4F6 /* UNSStepImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UNSStepImage.swift; sourceTree = ""; }; C98298312ADD7EDB0096C5B5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; @@ -1056,6 +1058,7 @@ 5B79F6522BA11B08002DA9BE /* WizardSheetDescriptionText.swift */, 5B79F6542BA123D4002DA9BE /* WizardSheetBadgeText.swift */, 5B29B58D2BEC392B008F6008 /* ActivityPubBadgeView.swift */, + C97B28892C10B07100DC1FC0 /* NosNavigationStack.swift */, ); path = Components; sourceTree = ""; @@ -2049,6 +2052,7 @@ CD2CF38E299E67F900332116 /* CardButtonStyle.swift in Sources */, A336DD3C299FD78000A0CBA0 /* Filter.swift in Sources */, DC2E54C82A700F1400C2CAAB /* UIDevice+Simulator.swift in Sources */, + C97B288A2C10B07100DC1FC0 /* NosNavigationStack.swift in Sources */, C98CA9072B14FBBF00929141 /* PagedNoteDataSource.swift in Sources */, C9A0DAEA29C6A34200466635 /* ActivityView.swift in Sources */, CD2CF390299E68BE00332116 /* NoteButton.swift in Sources */, diff --git a/Nos/Views/Components/NosNavigationStack.swift b/Nos/Views/Components/NosNavigationStack.swift new file mode 100644 index 000000000..4bf60a0bb --- /dev/null +++ b/Nos/Views/Components/NosNavigationStack.swift @@ -0,0 +1,36 @@ +import SwiftUI + +/// A NavigationStack that knows how to present views to display Nostr entities like `Events` and `Authors`. +/// Take care not to nest these. +struct NosNavigationStack: View { + + @Binding var path: NavigationPath + + var content: () -> Content + + var body: some View { + NavigationStack(path: $path) { + content() + .navigationDestination(for: Event.self) { note in + RepliesView(note: note) + } + .navigationDestination(for: URL.self) { url in + URLView(url: url) + } + .navigationDestination(for: ReplyToNavigationDestination.self) { destination in + RepliesView(note: destination.note, showKeyboard: true) + } + .navigationDestination(for: Author.self) { author in + ProfileView(author: author) + } + } + } +} + +#Preview { + @State var path = NavigationPath() + + return NosNavigationStack(path: $path) { + Text("hello world") + } +} diff --git a/Nos/Views/Discover/DiscoverTab.swift b/Nos/Views/Discover/DiscoverTab.swift index 80b078234..e9051c41f 100644 --- a/Nos/Views/Discover/DiscoverTab.swift +++ b/Nos/Views/Discover/DiscoverTab.swift @@ -27,7 +27,7 @@ struct DiscoverTab: View { // MARK: - View var body: some View { - NavigationStack(path: $router.discoverPath) { + NosNavigationStack(path: $router.discoverPath) { ZStack { if performingInitialLoad && searchController.query.isEmpty { FullscreenProgressView( @@ -65,19 +65,6 @@ struct DiscoverTab: View { analytics.showedDiscover() } } - .navigationDestination(for: Event.self) { note in - RepliesView(note: note) - } - .navigationDestination(for: URL.self) { url in URLView(url: url) } - .navigationDestination(for: ReplyToNavigationDestination.self) { destination in - RepliesView(note: destination.note, showKeyboard: true) - } - .navigationDestination(for: Author.self) { author in - ProfileView(author: author) - } - .navigationDestination(for: EditProfileDestination.self) { destination in - ProfileEditView(author: destination.profile) - } .nosNavigationBar(title: .localizable.discover) .toolbarBackground(.visible, for: .navigationBar) .toolbarBackground(Color.cardBgBottom, for: .navigationBar) diff --git a/Nos/Views/Home/HomeTab.swift b/Nos/Views/Home/HomeTab.swift index e010c4a72..7a0892268 100644 --- a/Nos/Views/Home/HomeTab.swift +++ b/Nos/Views/Home/HomeTab.swift @@ -6,24 +6,10 @@ struct HomeTab: View { @ObservedObject var user: Author @EnvironmentObject private var router: Router - @Environment(CurrentUser.self) var currentUser var body: some View { - NavigationStack(path: $router.homeFeedPath) { + NosNavigationStack(path: $router.homeFeedPath) { HomeFeedView(user: user) - .navigationDestination(for: Event.self) { note in - RepliesView(note: note) - } - .navigationDestination(for: Author.self) { author in - ProfileView(author: author) - } - .navigationDestination(for: EditProfileDestination.self) { destination in - ProfileEditView(author: destination.profile) - } - .navigationDestination(for: ReplyToNavigationDestination.self) { destination in - RepliesView(note: destination.note, showKeyboard: true) - } - .navigationDestination(for: URL.self) { url in URLView(url: url) } } } } diff --git a/Nos/Views/NotificationsView.swift b/Nos/Views/NotificationsView.swift index 5452af616..6339a9aac 100644 --- a/Nos/Views/NotificationsView.swift +++ b/Nos/Views/NotificationsView.swift @@ -63,7 +63,7 @@ struct NotificationsView: View { } var body: some View { - NavigationStack(path: $router.notificationsPath) { + NosNavigationStack(path: $router.notificationsPath) { ScrollView(.vertical) { LazyVStack { /// The fetch request for events has a `fetchLimit` set but it doesn't work, so we limit the @@ -90,19 +90,6 @@ struct NotificationsView: View { .padding(.top, 1) .nosNavigationBar(title: .localizable.notifications) .navigationBarItems(leading: SideMenuButton()) - .navigationDestination(for: Event.self) { note in - RepliesView(note: note) - } - .navigationDestination(for: URL.self) { url in URLView(url: url) } - .navigationDestination(for: ReplyToNavigationDestination.self) { destination in - RepliesView(note: destination.note, showKeyboard: true) - } - .navigationDestination(for: Author.self) { author in - ProfileView(author: author) - } - .navigationDestination(for: EditProfileDestination.self) { destination in - ProfileEditView(author: destination.profile) - } .refreshable { await subscribeToNewEvents() } diff --git a/Nos/Views/Profile/ProfileTab.swift b/Nos/Views/Profile/ProfileTab.swift index d04750399..05ab71b46 100644 --- a/Nos/Views/Profile/ProfileTab.swift +++ b/Nos/Views/Profile/ProfileTab.swift @@ -10,15 +10,9 @@ struct ProfileTab: View { @Binding var path: NavigationPath var body: some View { - NavigationStack(path: $path) { + NosNavigationStack(path: $path) { ProfileView(author: author, addDoubleTapToPop: true) .navigationBarItems(leading: SideMenuButton()) - .navigationDestination(for: Author.self) { profile in - ProfileView(author: profile) - } - .navigationDestination(for: EditProfileDestination.self) { destination in - ProfileEditView(author: destination.profile) - } } } } diff --git a/Nos/Views/Profile/ProfileView.swift b/Nos/Views/Profile/ProfileView.swift index e005c6fc9..aad6b3a61 100644 --- a/Nos/Views/Profile/ProfileView.swift +++ b/Nos/Views/Profile/ProfileView.swift @@ -108,13 +108,6 @@ struct ProfileView: View { } .background(Color.appBg) .nosNavigationBar(title: title) - .navigationDestination(for: Event.self) { note in - RepliesView(note: note) - } - .navigationDestination(for: URL.self) { url in URLView(url: url) } - .navigationDestination(for: ReplyToNavigationDestination.self) { destination in - RepliesView(note: destination.note, showKeyboard: true) - } .navigationDestination(for: MutesDestination.self) { _ in MutesView() } diff --git a/Nos/Views/SideMenuContent.swift b/Nos/Views/SideMenuContent.swift index 46a0ba4da..9f5338638 100644 --- a/Nos/Views/SideMenuContent.swift +++ b/Nos/Views/SideMenuContent.swift @@ -58,7 +58,7 @@ struct SideMenuContent: View { } var body: some View { - NavigationStack(path: $router.sideMenuPath) { + NosNavigationStack(path: $router.sideMenuPath) { VStack(alignment: .leading, spacing: 0) { profileHeader SideMenuRow( @@ -109,12 +109,6 @@ struct SideMenuContent: View { AboutView() } } - .navigationDestination(for: Author.self) { profile in - ProfileView(author: profile) - } - .navigationDestination(for: EditProfileDestination.self) { destination in - ProfileEditView(author: destination.profile) - } } } }