From ac6219450a4df13cc61dcd7adf78c18d81e8c36d Mon Sep 17 00:00:00 2001 From: Lumaa Date: Sat, 10 Aug 2024 15:43:47 +0200 Subject: [PATCH] Revisited Navigator --- Threaded/Components/TabsView.swift | 7 ++- Threaded/Data/Navigator.swift | 63 +++++++++++++++++++++++--- Threaded/Views/AccountView.swift | 2 +- Threaded/Views/ContentView.swift | 9 ++-- Threaded/Views/DiscoveryView.swift | 4 +- Threaded/Views/NotificationsView.swift | 2 +- Threaded/Views/TimelineView.swift | 2 +- 7 files changed, 73 insertions(+), 16 deletions(-) diff --git a/Threaded/Components/TabsView.swift b/Threaded/Components/TabsView.swift index aeed6ff..071935d 100644 --- a/Threaded/Components/TabsView.swift +++ b/Threaded/Components/TabsView.swift @@ -3,8 +3,8 @@ import SwiftUI struct TabsView: View { - @Binding var selectedTab: TabDestination - + @State var selectedTab: TabDestination = Navigator.shared.selectedTab + var postButton: () -> Void = {} var tapAction: () -> Void = {} var retapAction: () -> Void = {} @@ -92,6 +92,9 @@ struct TabsView: View { } .padding(.horizontal, 30) .background(Color.appBackground) + .onChange(of: selectedTab) { _, newValue in + Navigator.shared.selectedTab = newValue + } } } diff --git a/Threaded/Data/Navigator.swift b/Threaded/Data/Navigator.swift index 5d2fea4..f233e3f 100644 --- a/Threaded/Data/Navigator.swift +++ b/Threaded/Data/Navigator.swift @@ -5,17 +5,67 @@ import SwiftUI @Observable public class Navigator: ObservableObject { + public static var shared: Navigator = Navigator() + public var path: [RouterDestination] = [] public var presentedSheet: SheetDestination? public var presentedCover: SheetDestination? - public var selectedTab: TabDestination = .timeline - + public var selectedTab: TabDestination { + set { + change(to: newValue) + } + get { + return self.currentTab + } + } + private var currentTab: TabDestination = .timeline + + public private(set) var memorizedNav: [TabDestination : [RouterDestination]] = [:] + public var showTabbar: Bool { + get { + self.visiTabbar + } + set { + withAnimation(.spring) { + self.visiTabbar = newValue + } + } + } + private var visiTabbar: Bool = true + public var client: Client? public func navigate(to: RouterDestination) { path.append(to) } - + + /// Changes the current tab from the current ``Navigator`` class + func change(to tab: TabDestination) { + savePath() + + withAnimation(.spring) { + loadPath(from: tab) + } + } + + private func savePath() { + let lastTab: TabDestination = self.currentTab + let lastPath: [RouterDestination] = self.path + + memorizedNav.updateValue(lastPath, forKey: lastTab) + } + + private func loadPath(from tab: TabDestination) { + if let (newTab, newPath) = memorizedNav.first(where: { $0.key == tab }).map({ [$0.key : $0.value] })?.first { + self.currentTab = newTab + self.path = newPath + } else { + print("Couldn't find Navigator data from \(tab.id), created new ones") + self.currentTab = tab + self.path = [] + } + } + public func handle(url: URL) -> OpenURLAction.Result { guard let client = self.client else { return .systemAction } let path: String = url.absoluteString.replacingOccurrences(of: AppInfo.scheme, with: "") // remove all path @@ -64,15 +114,16 @@ public class Navigator: ObservableObject { } return OpenURLAction.Result.handled } - + + /// This only applies on the current path, not the saved ones in ``memorizedNav`` public func removeSettingsOfPath() { self.path = self.path.filter({ !RouterDestination.allSettings.contains($0) }) } } +/// This can be used for universal ``SheetDestination``s public class UniversalNavigator: Navigator { - static var shared: UniversalNavigator = UniversalNavigator() - public var tabNavigator: Navigator? + public static var `static`: UniversalNavigator = UniversalNavigator() } public enum TabDestination: Identifiable { diff --git a/Threaded/Views/AccountView.swift b/Threaded/Views/AccountView.swift index 9146b4d..c24d30f 100644 --- a/Threaded/Views/AccountView.swift +++ b/Threaded/Views/AccountView.swift @@ -5,7 +5,7 @@ import SwiftUI struct AccountView: View { @Environment(AccountManager.self) private var accountManager: AccountManager - @State private var navigator: Navigator = Navigator() + @State private var navigator: Navigator = Navigator.shared @State public var account: Account var body: some View { diff --git a/Threaded/Views/ContentView.swift b/Threaded/Views/ContentView.swift index e2ac121..3392b97 100644 --- a/Threaded/Views/ContentView.swift +++ b/Threaded/Views/ContentView.swift @@ -8,12 +8,13 @@ struct ContentView: View { private var huggingFace: HuggingFace = HuggingFace() @State private var preferences: UserPreferences = .defaultPreferences - @StateObject private var uniNavigator = UniversalNavigator.shared + @State private var navigator: Navigator = .shared + @StateObject private var uniNavigator = UniversalNavigator.static @StateObject private var accountManager: AccountManager = AccountManager.shared var body: some View { ZStack { - TabView(selection: $uniNavigator.selectedTab, content: { + TabView(selection: $navigator.selectedTab, content: { if accountManager.getAccount() != nil { TimelineView(timelineModel: FetchTimeline(client: accountManager.forceClient())) .background(Color.appBackground) @@ -40,8 +41,10 @@ struct ContentView: View { } .frame(maxWidth: appDelegate.windowWidth) .overlay(alignment: .bottom) { - TabsView(selectedTab: $uniNavigator.selectedTab, postButton: { + TabsView(postButton: { uniNavigator.presentedSheet = .post(content: "", replyId: nil, editId: nil) + }, retapAction: { + Navigator.shared.path = [] }) .safeAreaPadding(.vertical, 10) .zIndex(10) diff --git a/Threaded/Views/DiscoveryView.swift b/Threaded/Views/DiscoveryView.swift index 502a844..1645de0 100644 --- a/Threaded/Views/DiscoveryView.swift +++ b/Threaded/Views/DiscoveryView.swift @@ -5,8 +5,8 @@ import SwiftUI struct DiscoveryView: View { @Environment(AccountManager.self) private var accountManager: AccountManager - @State private var navigator: Navigator = Navigator() - + @State private var navigator: Navigator = Navigator.shared + @State private var searchQuery: String = "" @State private var results: [String : SearchResults] = [:] @State private var querying: Bool = false diff --git a/Threaded/Views/NotificationsView.swift b/Threaded/Views/NotificationsView.swift index 39cb16c..f7d3525 100644 --- a/Threaded/Views/NotificationsView.swift +++ b/Threaded/Views/NotificationsView.swift @@ -6,7 +6,7 @@ import TipKit struct NotificationsView: View { @Environment(AccountManager.self) private var accountManager - @State private var navigator: Navigator = Navigator() + @State private var navigator: Navigator = Navigator.shared @State private var notifications: [GroupedNotification] = [] @State private var loadingNotifs: Bool = true @State private var lastId: Int? = nil diff --git a/Threaded/Views/TimelineView.swift b/Threaded/Views/TimelineView.swift index 32cfe3a..bb59f7d 100644 --- a/Threaded/Views/TimelineView.swift +++ b/Threaded/Views/TimelineView.swift @@ -5,7 +5,7 @@ import SwiftData struct TimelineView: View { @Environment(AccountManager.self) private var accountManager: AccountManager - @State var navigator: Navigator = Navigator() + @State var navigator: Navigator = Navigator.shared @State private var showPicker: Bool = false @State private var timelines: [TimelineFilter] = [.home, .trending, .local, .federated]