import SwiftUI struct MainView: View { @EnvironmentObject var settings: SettingsManager @State private var selectedTab: Int = 0 @State private var manager = BooruManager(.yandere) var body: some View { platformSpecificContent .environmentObject(settings) .environmentObject(manager) .onChange(of: settings.preferredBooru) { _, newState in updateManager(newState) } .onChange(of: manager.historyIndex) { _, _ in manager.selectedPost = nil } .onAppear(perform: initializeManager) .onChange(of: settings.providerCredentials) { initializeManager() } #if os(macOS) .onChange(of: selectedTab) { _, newValue in if newValue == 0 { Task(priority: .userInitiated) { await manager.fetchPosts() } } } #endif } @ViewBuilder private var tabViewContent: some View { if #available(iOS 26, macOS 15.0, *) { TabView(selection: $selectedTab) { Tab("Posts", systemImage: "rectangle.stack", value: 0) { ContentView(selectedTab: $selectedTab) } Tab("Bookmarks", systemImage: "bookmark", value: 1) { NavigationStack { BookmarksView(selectedTab: $selectedTab) } } #if os(macOS) Tab("Search History", systemImage: "clock.arrow.circlepath", value: 3) { PostGridSearchHistoryView( selectedTab: $selectedTab, isPresented: .constant(false) ) } #endif #if DEBUG || !os(macOS) Tab("Settings", systemImage: "gear", value: 2) { SettingsView() } #endif } } else { TabView(selection: $selectedTab) { ContentView(selectedTab: $selectedTab) .tabItem { Label("Posts", systemImage: "rectangle.stack") } .tag(0) NavigationStack { BookmarksView(selectedTab: $selectedTab) } .tabItem { Label("Bookmarks", systemImage: "bookmark") } .tag(1) #if os(macOS) NavigationStack { PostGridSearchHistoryView( selectedTab: $selectedTab, isPresented: .constant(false) ) } .tabItem { Label("Search History", systemImage: "clock.arrow.circlepath") } .tag(3) #endif #if DEBUG || !os(macOS) SettingsView() .tabItem { Label("Settings", systemImage: "gear") } .tag(2) #endif } } } @ViewBuilder private var platformSpecificContent: some View { if #available(iOS 26, *) { tabViewContent #if !os(macOS) .tabBarMinimizeBehavior(.onScrollDown) #endif } else { tabViewContent } } private func updateManager(_ provider: BooruProvider) { let previousSearchText = manager.searchText manager = BooruManager( provider, credentials: settings.providerCredentials .first { $0.provider == settings.preferredBooru } ) manager.searchText = previousSearchText Task(priority: .userInitiated) { if manager.searchText.isEmpty { await manager.fetchPosts() } else { await manager.performSearch(settings: settings) } } } private func initializeManager() { manager = BooruManager( settings.preferredBooru, credentials: settings.providerCredentials .first { $0.provider == settings.preferredBooru } ) Task(priority: .userInitiated) { if manager.posts.isEmpty { await manager.fetchPosts() } } } } #Preview { #if os(macOS) let screenSize = NSScreen.main?.frame.size ?? CGSize(width: 1_920, height: 1_080) let heightCoefficient = screenSize.height / 1_080 let widthCoefficient = screenSize.width / 1_440 #endif MainView() .environmentObject(SettingsManager()) #if os(macOS) .frame( width: screenSize.width / widthCoefficient, height: screenSize.height / heightCoefficient ) #endif }