diff options
| author | Fuwn <[email protected]> | 2025-06-18 04:18:12 -0700 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2025-06-18 04:18:12 -0700 |
| commit | d4ab6da2541e2dcb325590c2ed347413384cb802 (patch) | |
| tree | 0f4c574e96cc6ba793b7d244ea4da474eb1f7b23 | |
| parent | feat: Development commit (diff) | |
| download | sora-testing-d4ab6da2541e2dcb325590c2ed347413384cb802.tar.xz sora-testing-d4ab6da2541e2dcb325590c2ed347413384cb802.zip | |
feat: Development commit
| -rw-r--r-- | Sora/Data/Booru/BooruManager.swift | 41 | ||||
| -rw-r--r-- | Sora/Extensions/Array+Chunked.swift | 7 | ||||
| -rw-r--r-- | Sora/Views/Post/Grid/PostGridView.swift | 2 |
3 files changed, 42 insertions, 8 deletions
diff --git a/Sora/Data/Booru/BooruManager.swift b/Sora/Data/Booru/BooruManager.swift index f0cad76..b7347a0 100644 --- a/Sora/Data/Booru/BooruManager.swift +++ b/Sora/Data/Booru/BooruManager.swift @@ -2,7 +2,7 @@ import Alamofire import SwiftUI @MainActor -class BooruManager: ObservableObject { +class BooruManager: ObservableObject { // swiftlint:disable:this type_body_length // MARK: - Published Properties @Published var posts: [BooruPost] = [] @Published var allTags: [BooruTag] = [] @@ -93,11 +93,20 @@ class BooruManager: ObservableObject { do { let data = try await requestURL(url) - let newPosts = parsePosts(from: data).sorted { $0.id > $1.id } + let newPosts = await withCheckedContinuation { continuation in + DispatchQueue.global(qos: .userInitiated).async { + let parsedPosts = self.parsePosts(from: data).sorted { $0.id > $1.id } + + continuation.resume(returning: parsedPosts) + } + } let cacheEntry = BooruPageCacheEntry(posts: newPosts, timestamp: Date()) pageCache.setObject(cacheEntry, forKey: cacheKey) - updatePosts(newPosts, replace: replace) + + withAnimation(nil) { + updatePosts(newPosts, replace: replace) + } } catch { self.error = error @@ -281,12 +290,28 @@ class BooruManager: ObservableObject { endOfData = newPosts.isEmpty - if !endOfData { - posts += newPosts + guard !endOfData else { return } - postIndexMap.merge( - Dictionary(uniqueKeysWithValues: newPosts.enumerated().map { ($0.element.id, $0.offset) }) - ) { _, new in new } + Task.detached { + let batchSize = 10 + + for chunk in newPosts.chunked(into: batchSize) { + try? await Task.sleep(nanoseconds: 30_000_000) // 30 ms + + await MainActor.run { + withTransaction(Transaction(animation: nil)) { + self.posts += chunk + + self.postIndexMap.merge( + Dictionary( + uniqueKeysWithValues: chunk.enumerated().map { post in + (post.element.id, post.offset) + } + ) + ) { _, newIndex in newIndex } + } + } + } } } diff --git a/Sora/Extensions/Array+Chunked.swift b/Sora/Extensions/Array+Chunked.swift new file mode 100644 index 0000000..d6d56e9 --- /dev/null +++ b/Sora/Extensions/Array+Chunked.swift @@ -0,0 +1,7 @@ +extension Array { + func chunked(into size: Int) -> [[Element]] { + stride(from: 0, to: count, by: size).map { index in + Array(self[index..<Swift.min(index + size, count)]) + } + } +} diff --git a/Sora/Views/Post/Grid/PostGridView.swift b/Sora/Views/Post/Grid/PostGridView.swift index 9dce682..ac6aeaa 100644 --- a/Sora/Views/Post/Grid/PostGridView.swift +++ b/Sora/Views/Post/Grid/PostGridView.swift @@ -73,6 +73,7 @@ struct PostGridView: View { // swiftlint:disable:this type_body_length .id(post.id) } } + .transaction { $0.animation = nil } } } #if os(macOS) @@ -87,6 +88,7 @@ struct PostGridView: View { // swiftlint:disable:this type_body_length .id(post.id) } .gridStyle(columns: columnCount) + .transaction { $0.animation = nil } #if os(macOS) .padding(8) #else |