summaryrefslogtreecommitdiff
path: root/Sora/Views/Post/Details/Carousel
diff options
context:
space:
mode:
authorFuwn <[email protected]>2025-03-02 17:18:14 -0800
committerFuwn <[email protected]>2025-03-02 17:18:14 -0800
commit40fb6c23224c2d9aad265e8f671817028725dcf6 (patch)
treeddf0f1a6c96b666554c7bbe0fe20e94f820b0a84 /Sora/Views/Post/Details/Carousel
parentfeat: Development commit (diff)
downloadsora-testing-40fb6c23224c2d9aad265e8f671817028725dcf6.tar.xz
sora-testing-40fb6c23224c2d9aad265e8f671817028725dcf6.zip
feat: Development commit
Diffstat (limited to 'Sora/Views/Post/Details/Carousel')
-rw-r--r--Sora/Views/Post/Details/Carousel/PostDetailsCarouselItemView.swift37
-rw-r--r--Sora/Views/Post/Details/Carousel/PostDetailsCarouselView.swift84
2 files changed, 121 insertions, 0 deletions
diff --git a/Sora/Views/Post/Details/Carousel/PostDetailsCarouselItemView.swift b/Sora/Views/Post/Details/Carousel/PostDetailsCarouselItemView.swift
new file mode 100644
index 0000000..c4aa292
--- /dev/null
+++ b/Sora/Views/Post/Details/Carousel/PostDetailsCarouselItemView.swift
@@ -0,0 +1,37 @@
+import SwiftUI
+
+struct PostDetailsCarouselItemView: View {
+ var post: BooruPost
+ var index: Int
+ @Binding var loadingStage: BooruPostLoadingState
+ var imageURL: (BooruPost) -> URL?
+ private var systemBackgroundColor: Color {
+ #if os(iOS)
+ return Color(.systemBackground)
+ #elseif os(macOS)
+ return Color(.windowBackgroundColor)
+ #else
+ return Color.gray
+ #endif
+ }
+
+ var body: some View {
+ ZStack {
+ PostDetailsImageView(
+ url: post.previewURL,
+ loadingStage: $loadingStage
+ )
+
+ PostDetailsImageView(
+ url: imageURL(post),
+ loadingStage: $loadingStage,
+ finalLoadingState: .loaded,
+ post: post
+ )
+ .background(
+ loadingStage == .loaded ? systemBackgroundColor : Color.clear
+ )
+ }
+ .tag(index)
+ }
+}
diff --git a/Sora/Views/Post/Details/Carousel/PostDetailsCarouselView.swift b/Sora/Views/Post/Details/Carousel/PostDetailsCarouselView.swift
new file mode 100644
index 0000000..61d3aef
--- /dev/null
+++ b/Sora/Views/Post/Details/Carousel/PostDetailsCarouselView.swift
@@ -0,0 +1,84 @@
+import SwiftUI
+
+struct PostDetailsCarouselView: View {
+ @EnvironmentObject var manager: BooruManager
+ @EnvironmentObject var settings: SettingsManager
+ let posts: [BooruPost]
+ let focusedPost: BooruPost?
+ @Binding var loadingStage: BooruPostLoadingState
+ @State private var currentIndex: Int
+ private let cacheManager = ImageCacheManager.shared
+
+ init(
+ posts: [BooruPost],
+ loadingStage: Binding<BooruPostLoadingState>,
+ focusedPost: BooruPost? = nil
+ ) {
+ self.posts = posts
+ self.focusedPost = focusedPost
+ _loadingStage = loadingStage
+
+ if let focused = focusedPost,
+ let index = posts.firstIndex(where: { $0.id == focused.id })
+ {
+ self._currentIndex = State(initialValue: index)
+ } else {
+ self._currentIndex = State(initialValue: 0)
+ }
+ }
+
+ func imageURL(post: BooruPost) -> URL? {
+ switch settings.detailViewQuality {
+ case .preview:
+ post.previewURL
+
+ case .sample:
+ post.sampleURL
+
+ case .original:
+ post.fileURL
+ }
+ }
+
+ var body: some View {
+ TabView(selection: $currentIndex) {
+ ForEach(Array(posts.enumerated()), id: \.offset) { index, post in
+ PostDetailsCarouselItemView(
+ post: post,
+ index: index,
+ loadingStage: $loadingStage,
+ imageURL: imageURL
+ )
+ }
+ }
+ .onChange(of: currentIndex) {
+ if currentIndex == posts.count - 1 { manager.loadNextPage() }
+
+ preloadNearbyImages()
+ }
+ .onAppear(perform: preloadNearbyImages)
+ #if !os(macOS)
+ .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
+ #endif
+ }
+
+ private func preloadNearbyImages() {
+ let preloadRange = settings.preloadedCarouselImages
+
+ guard preloadRange > 0 else { return }
+
+ let startIndex = max(0, currentIndex - preloadRange)
+ let endIndex = min(posts.count - 1, currentIndex + preloadRange)
+ var urlsToPreload: [URL] = []
+
+ for index in startIndex...endIndex {
+ if let url = imageURL(post: posts[index]) {
+ urlsToPreload.append(url)
+ }
+
+ urlsToPreload.append(posts[index].previewURL)
+ }
+
+ cacheManager.preloadImages(urlsToPreload)
+ }
+}