summaryrefslogtreecommitdiff
path: root/Sora/Views/Post/Details
diff options
context:
space:
mode:
Diffstat (limited to 'Sora/Views/Post/Details')
-rw-r--r--Sora/Views/Post/Details/Carousel/PostDetailsCarouselView.swift29
-rw-r--r--Sora/Views/Post/Details/PostDetailsView.swift39
2 files changed, 63 insertions, 5 deletions
diff --git a/Sora/Views/Post/Details/Carousel/PostDetailsCarouselView.swift b/Sora/Views/Post/Details/Carousel/PostDetailsCarouselView.swift
index 94d258e..f733a89 100644
--- a/Sora/Views/Post/Details/Carousel/PostDetailsCarouselView.swift
+++ b/Sora/Views/Post/Details/Carousel/PostDetailsCarouselView.swift
@@ -5,6 +5,7 @@ struct PostDetailsCarouselView: View {
@EnvironmentObject var settings: SettingsManager
let posts: [BooruPost]
let focusedPost: BooruPost?
+ let onFocusedPostChange: (BooruPost) -> Void
@Binding var loadingStage: BooruPostLoadingState
@State private var currentIndex: Int?
private let cacheManager = ImageCacheManager.shared
@@ -12,10 +13,12 @@ struct PostDetailsCarouselView: View {
init(
posts: [BooruPost],
loadingStage: Binding<BooruPostLoadingState>,
- focusedPost: BooruPost? = nil
+ focusedPost: BooruPost? = nil,
+ onFocusedPostChange: @escaping (BooruPost) -> Void = { _ in }
) {
self.posts = posts
self.focusedPost = focusedPost
+ self.onFocusedPostChange = onFocusedPostChange
_loadingStage = loadingStage
if let focused = focusedPost,
@@ -61,7 +64,9 @@ struct PostDetailsCarouselView: View {
.scrollIndicators(.hidden)
.scrollTargetBehavior(.paging)
.onChange(of: currentIndex) {
- guard let currentIndex else { return }
+ guard let currentIndex, posts.indices.contains(currentIndex) else { return }
+
+ onFocusedPostChange(posts[currentIndex])
Task(priority: .utility) {
if currentIndex == posts.count - 1 { await manager.loadNextPage() }
@@ -69,7 +74,13 @@ struct PostDetailsCarouselView: View {
preloadNearbyImages()
}
- .onAppear(perform: preloadNearbyImages)
+ .onChange(of: focusedPost?.id) {
+ syncCurrentIndexWithFocus()
+ }
+ .onAppear {
+ syncCurrentIndexWithFocus()
+ preloadNearbyImages()
+ }
}
private func preloadNearbyImages() {
@@ -92,4 +103,16 @@ struct PostDetailsCarouselView: View {
cacheManager.preloadImages(urlsToPreload)
}
+
+ private func syncCurrentIndexWithFocus() {
+ if let focusedPost,
+ let index = posts.firstIndex(where: { $0.id == focusedPost.id })
+ {
+ currentIndex = index
+ onFocusedPostChange(posts[index])
+ } else if !posts.isEmpty {
+ currentIndex = 0
+ onFocusedPostChange(posts[0])
+ }
+ }
}
diff --git a/Sora/Views/Post/Details/PostDetailsView.swift b/Sora/Views/Post/Details/PostDetailsView.swift
index 9c55798..bb58c49 100644
--- a/Sora/Views/Post/Details/PostDetailsView.swift
+++ b/Sora/Views/Post/Details/PostDetailsView.swift
@@ -7,6 +7,7 @@ struct PostDetailsView: View {
@Binding var navigationPath: NavigationPath
@State private var loadingStage: BooruPostLoadingState = .loadingPreview
@State private var isTagsSheetPresented = false
+ @State private var activePost: BooruPost
// swiftlint:disable:next discouraged_optional_collection
let posts: [BooruPost]?
let baseSearchText: String?
@@ -33,6 +34,7 @@ struct PostDetailsView: View {
) {
self.post = post
self._navigationPath = navigationPath
+ self._activePost = State(initialValue: post)
self.posts = posts
self.baseSearchText = baseSearchText
}
@@ -44,7 +46,7 @@ struct PostDetailsView: View {
}
private var currentPost: BooruPost {
- manager.selectedPost ?? post
+ activePost
}
var body: some View {
@@ -67,7 +69,8 @@ struct PostDetailsView: View {
PostDetailsCarouselView(
posts: filteredPosts,
loadingStage: $loadingStage,
- focusedPost: currentPost
+ focusedPost: currentPost,
+ onFocusedPostChange: updateActivePost
)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
#endif
@@ -149,6 +152,16 @@ struct PostDetailsView: View {
tagsSheetContent()
}
}
+ .onAppear {
+ syncActivePost()
+ }
+ .onChange(of: post.id) {
+ activePost = post
+ syncActivePost()
+ }
+ .onChange(of: manager.selectedPost?.id) {
+ syncActivePost()
+ }
}
@ViewBuilder
@@ -167,4 +180,26 @@ struct PostDetailsView: View {
)
#endif
}
+
+ private func updateActivePost(_ post: BooruPost) {
+ guard activePost.id != post.id else { return }
+
+ activePost = post
+ }
+
+ private func syncActivePost() {
+ #if os(macOS)
+ if let selectedPost = manager.selectedPost {
+ updateActivePost(selectedPost)
+ } else {
+ updateActivePost(post)
+ }
+ #else
+ if let selectedPost = manager.selectedPost, posts == nil {
+ updateActivePost(selectedPost)
+ } else {
+ updateActivePost(post)
+ }
+ #endif
+ }
}