diff options
| author | Fuwn <[email protected]> | 2025-09-11 22:59:04 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2025-09-11 22:59:04 -0700 |
| commit | 1af757409c5cf47b6c515d64c0656759129cd950 (patch) | |
| tree | 7e8aab9df226f93cb339da0bd985fd934053e596 | |
| parent | feat: Development commit (diff) | |
| download | sora-testing-1af757409c5cf47b6c515d64c0656759129cd950.tar.xz sora-testing-1af757409c5cf47b6c515d64c0656759129cd950.zip | |
feat: Development commit
| -rw-r--r-- | Sora/Data/Booru/BooruManager.swift | 72 | ||||
| -rw-r--r-- | Sora/Views/Post/Grid/PostGridView.swift | 13 |
2 files changed, 66 insertions, 19 deletions
diff --git a/Sora/Data/Booru/BooruManager.swift b/Sora/Data/Booru/BooruManager.swift index ce5eaec..3e94b56 100644 --- a/Sora/Data/Booru/BooruManager.swift +++ b/Sora/Data/Booru/BooruManager.swift @@ -97,12 +97,34 @@ class BooruManager: ObservableObject { // swiftlint:disable:this type_body_leng defer { isLoading = false } - var finalPosts: [BooruPost] = [] + let finalPosts = await fetchPostsWithRetry(url: url) + + if Task.isCancelled { return } + + let cacheEntry = BooruPageCacheEntry( + posts: finalPosts, + timestamp: Date(), + expiration: cacheDuration + ) + + pageCache.setObject(cacheEntry, forKey: cacheKey, cost: finalPosts.count) + + withAnimation(nil) { + updatePosts(finalPosts, replace: replace) + } + } + + private func fetchPostsWithRetry(url: URL) async -> [BooruPost] { let maxAttempts = 4 for attempt in 1...maxAttempts { + if Task.isCancelled { return [] } + do { let data = try await requestURL(url) + + if Task.isCancelled { return [] } + let flavor = self.flavor let provider = self.provider let newPosts = await withCheckedContinuation { continuation in @@ -118,35 +140,27 @@ class BooruManager: ObservableObject { // swiftlint:disable:this type_body_leng } } - if !newPosts.isEmpty { - finalPosts = newPosts + if Task.isCancelled { return [] } - break + if !newPosts.isEmpty { + return newPosts } if attempt < maxAttempts { try await Task.sleep(for: .seconds(0.5 * Double(attempt))) } } catch { - self.error = error + if !Task.isCancelled { + self.error = error - debugPrint("BooruManager.fetchPosts(\(attempt)): \(error)") + debugPrint("BooruManager.fetchPosts(\(attempt)): \(error)") + } break } } - let cacheEntry = BooruPageCacheEntry( - posts: finalPosts, - timestamp: Date(), - expiration: cacheDuration - ) - - pageCache.setObject(cacheEntry, forKey: cacheKey, cost: finalPosts.count) - - withAnimation(nil) { - updatePosts(finalPosts, replace: replace) - } + return [] } func clearCachedPages() { @@ -205,11 +219,21 @@ class BooruManager: ObservableObject { // swiftlint:disable:this type_body_leng let previousQuery = searchHistory[historyIndex] + if previousQuery.provider != provider { + provider = previousQuery.provider + flavor = BooruProviderFlavor(provider: provider) + domain = provider.domain + } + searchText = previousQuery.tags.joined(separator: " ") cancelCurrentTask() - currentTask = Task { isNavigatingHistory = false } + currentTask = Task { + await fetchPosts(page: 1, tags: previousQuery.tags, replace: true) + + isNavigatingHistory = false + } } func goForwardInHistory() { @@ -220,11 +244,21 @@ class BooruManager: ObservableObject { // swiftlint:disable:this type_body_leng let nextQuery = searchHistory[historyIndex] + if nextQuery.provider != provider { + provider = nextQuery.provider + flavor = BooruProviderFlavor(provider: provider) + domain = provider.domain + } + searchText = nextQuery.tags.joined(separator: " ") cancelCurrentTask() - currentTask = Task { isNavigatingHistory = false } + currentTask = Task { + await fetchPosts(page: 1, tags: nextQuery.tags, replace: true) + + isNavigatingHistory = false + } } func searchTags(name: String) async -> [BooruTag] { diff --git a/Sora/Views/Post/Grid/PostGridView.swift b/Sora/Views/Post/Grid/PostGridView.swift index 5c071b8..a5ff85a 100644 --- a/Sora/Views/Post/Grid/PostGridView.swift +++ b/Sora/Views/Post/Grid/PostGridView.swift @@ -240,6 +240,13 @@ struct PostGridView: View { // swiftlint:disable:this type_body_length } } } + .onChange(of: navigationPath) { _, _ in + if initialTag == nil && !manager.isNavigatingHistory && !manager.isLoading { + Task(priority: .userInitiated) { + await manager.fetchPosts(page: 1, tags: manager.tags, replace: true) + } + } + } .onAppear { if let initialTag { if localSearchText.isEmpty || !hasAppearedBefore { @@ -270,6 +277,12 @@ struct PostGridView: View { // swiftlint:disable:this type_body_length } } } + } else { + if !manager.isNavigatingHistory && !manager.isLoading { + Task(priority: .userInitiated) { + await manager.fetchPosts(page: 1, tags: manager.tags, replace: true) + } + } } } .toolbar { |