import SwiftUI import WaterfallGrid struct PostGridView: View { @EnvironmentObject var settings: Settings @EnvironmentObject var manager: BooruManager @Environment(\.isSearching) private var isSearching var filteredPosts: [BooruPost] { manager.posts.filter { settings.displayRatings.contains($0.rating) } .sorted { $0.id > $1.id } } var body: some View { ScrollViewReader { _ in ScrollView { if filteredPosts.isEmpty { ProgressView() .padding() } WaterfallGrid(filteredPosts, id: \.id) { post in Button { manager.selectedPost = post } label: { PostGridThumbnailView( post: post, posts: filteredPosts ) } .buttonStyle(PlainButtonStyle()) .contextMenu { Button(action: { manager.selectedPost = post }) { Label("Select Post", systemImage: "arrow.right.circle") } } } .gridStyle(columns: settings.columns) .padding(8) } .searchable(text: $manager.searchText, prompt: "Tags") .searchSuggestions { if settings.searchSuggestions { SearchSuggestionsView( tags: manager.allTags, searchText: $manager.searchText ) } } .onSubmit(of: .search, manager.performSearch) .navigationDestination(for: BooruPost.self) { post in PostDetailsView(post: post) } .onChange(of: manager.searchText) { _, _ in if manager.searchText.isEmpty, !isSearching { Task { manager.performSearch() } } } .toolbar { #if os(macOS) ToolbarItem { Button(action: { Task { await manager.fetchPosts(page: 1, tags: manager.tags, replace: true) } }) { Label("Refresh", systemImage: "arrow.clockwise") } .disabled(manager.isLoading) } #endif #if os(macOS) ToolbarItem { Button(action: { Task { manager.loadNextPage() } }) { Label("Manually Load Next Page", systemImage: "chevron.right") } .disabled(manager.isLoading) } #else ToolbarItem(placement: .bottomBar) { Button(action: { Task { manager.loadNextPage() } }) { Label("Manually Load Next Page", systemImage: "chevron.right") } .disabled(manager.isLoading) } #endif if !manager.tags.isEmpty { #if os(macOS) ToolbarItem { PostGridBookmarkButtonView() } #else ToolbarItem(placement: .bottomBar) { PostGridBookmarkButtonView() } #endif } } .navigationTitle("Posts") .refreshable { await manager.fetchPosts(page: 1, tags: manager.tags, replace: true) } } } }