diff options
| author | Fuwn <[email protected]> | 2025-02-18 23:39:51 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2025-02-19 00:00:29 -0800 |
| commit | 320ce31337ed60cae24a0374fa2d6d79237a6bfe (patch) | |
| tree | ad1e93799efeb8e7a16521e3ab958c911f73f617 /Sora/Views/ContentView.swift | |
| parent | feat: Initial commit (diff) | |
| download | sora-testing-320ce31337ed60cae24a0374fa2d6d79237a6bfe.tar.xz sora-testing-320ce31337ed60cae24a0374fa2d6d79237a6bfe.zip | |
feat: Development commit
Diffstat (limited to 'Sora/Views/ContentView.swift')
| -rw-r--r-- | Sora/Views/ContentView.swift | 186 |
1 files changed, 10 insertions, 176 deletions
diff --git a/Sora/Views/ContentView.swift b/Sora/Views/ContentView.swift index 38516ef..9ec56a4 100644 --- a/Sora/Views/ContentView.swift +++ b/Sora/Views/ContentView.swift @@ -1,198 +1,32 @@ import SwiftUI struct ContentView: View { - @State private var posts: [MoebooruPost] = [] - #if os(macOS) - @State private var selectedPost: YanderePost? - #endif - @State private var searchQuery = "" - @State private var currentPage = 1 - @State private var isLoading: Bool = false - @State private var largerThumbnails: Bool = false - var tags: [String] { - if searchQuery.isEmpty { - return [] - } - - return searchQuery - .split(separator: ",") - .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) } - .filter { !$0.isEmpty } - } - - @State var softLimit: Int = 100 - var softLimitCGFloat: CGFloat { - CGFloat(softLimit) - } - - var columns: [GridItem] { - return [ - GridItem(.adaptive(minimum: softLimitCGFloat)), - ] - } + @EnvironmentObject var settings: Settings + @StateObject private var manager = MoebooruManager() var body: some View { #if os(macOS) NavigationSplitView { - ScrollView { - if self.posts.isEmpty { - ProgressView() - .frame(width: softLimitCGFloat, height: softLimitCGFloat) - } - - LazyVGrid(columns: columns) { - ForEach(posts, id: \.id) { post in - Button { - selectedPost = post - } label: { - PostView(post: post, softLimit: softLimitCGFloat) - .frame(maxWidth: .infinity) - } - .buttonStyle(PlainButtonStyle()) - - if post == posts.last { - ProgressView() - .onAppear(perform: loadNextPage) - .padding() - } - } - } - } - .searchable(text: $searchQuery, prompt: "Tags") - .onSubmit(of: .search, performSearch) - .toolbar { - ToolbarItem { - Button(action: { - Task { - await fetchPosts(page: 1, tags: tags, replace: true) - } - }) { - Label("Refresh", systemImage: "arrow.clockwise") - } - } - } + PostGridView( + manager: manager + ) } detail: { - if let post = selectedPost { - PostDetailView(post: post) + if let post = manager.selectedPost { + PostDetailsView(post: post) } else { - Text("Select a post") + Text("Select a post.") .foregroundColor(.secondary) } } - .task { - await fetchPosts(page: currentPage) - } #else NavigationStack { - ScrollView { - if self.posts.isEmpty { - ProgressView() - .frame(width: softLimitCGFloat, height: softLimitCGFloat) - } - - LazyVGrid(columns: columns, spacing: 10) { - ForEach(posts, id: \.id) { post in - NavigationLink(value: post) { - PostView( - post: post, - softLimit: softLimitCGFloat, - thumbnailMode: self.largerThumbnails ? .sample : .preview - ) - .frame(maxWidth: .infinity) - } - - if post == posts.last { - ProgressView() - .onAppear(perform: loadNextPage) - .padding() - } - } - } - } - .searchable(text: $searchQuery, prompt: "Tags") - .onSubmit(of: .search, performSearch) - .navigationDestination(for: MoebooruPost.self) { post in - PostDetailView(post: post) - } - .task { - await fetchPosts(page: currentPage) - } - .toolbar { - ToolbarItem { - TextField( - softLimit.description, - value: $softLimit, - format: .number - ) - } - - ToolbarItem { - Toggle("Full size thumbnails", isOn: $largerThumbnails) - } - - ToolbarItem { - Button(action: { - Task { - await fetchPosts(page: 1, tags: tags, replace: true) - } - }) { - Label("Refresh", systemImage: "arrow.clockwise") - } - } - } + PostGridView(manager: manager) } #endif } - - func fetchPosts(page: Int = 1, limit: Int = 100, tags: [String] = [], replace: Bool = false) async { - guard !isLoading else { return } - - isLoading = true - - defer { isLoading = false } - - guard let url = URL(string: "https://yande.re/post.xml?page=\(page)&limit=\(limit)&tags=\(tags.joined(separator: "+"))") else { return } - do { - let (data, _) = try await URLSession.shared.data(from: url) - - DispatchQueue.main.async { - if replace { - self.posts = [] - self.currentPage = 1 - } - - self.posts += Array(Set(MoebooruXMLParser().parse(data: data))).sorted { $0.id > $1.id } - } - } catch { - #if DEBUG - print(error) - #endif - } - } - - func performSearch() { - Task { - await fetchPosts( - page: 1, - tags: tags, - replace: true - ) - } - } - - func loadNextPage() { - guard !isLoading else { return } - - Task { - await fetchPosts(page: currentPage + 1, tags: tags) - - DispatchQueue.main.async { - currentPage += 1 - } - } - } } #Preview { ContentView() + .environmentObject(Settings()) } |