Revisited Navigator

This commit is contained in:
Lumaa 2024-08-10 15:43:47 +02:00
parent d958940d81
commit ac6219450a
7 changed files with 73 additions and 16 deletions

View File

@ -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
}
}
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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]