summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-06-18 04:18:12 -0700
committerFuwn <[email protected]>2025-06-18 04:18:12 -0700
commitd4ab6da2541e2dcb325590c2ed347413384cb802 (patch)
tree0f4c574e96cc6ba793b7d244ea4da474eb1f7b23
parentfeat: Development commit (diff)
downloadsora-testing-d4ab6da2541e2dcb325590c2ed347413384cb802.tar.xz
sora-testing-d4ab6da2541e2dcb325590c2ed347413384cb802.zip
feat: Development commit
-rw-r--r--Sora/Data/Booru/BooruManager.swift41
-rw-r--r--Sora/Extensions/Array+Chunked.swift7
-rw-r--r--Sora/Views/Post/Grid/PostGridView.swift2
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