diff options
| author | Fuwn <[email protected]> | 2025-03-02 17:18:14 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2025-03-02 17:18:14 -0800 |
| commit | 40fb6c23224c2d9aad265e8f671817028725dcf6 (patch) | |
| tree | ddf0f1a6c96b666554c7bbe0fe20e94f820b0a84 /Sora/Views/Post/Details/Carousel | |
| parent | feat: Development commit (diff) | |
| download | sora-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.swift | 37 | ||||
| -rw-r--r-- | Sora/Views/Post/Details/Carousel/PostDetailsCarouselView.swift | 84 |
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) + } +} |