Skip to content

Commit 910ad8d

Browse files
committed
updated loading logic
1 parent ca648e5 commit 910ad8d

File tree

1 file changed

+39
-13
lines changed

1 file changed

+39
-13
lines changed

MacImageManager/MacImageManager/Views/PaneImageViewer.swift

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@ import SwiftUI
1010
struct PaneImageViewer: View {
1111
let selectedImage: URL?
1212
@State private var loadedImage: NSImage?
13+
@State private var currentLoadingURL: URL?
14+
@State private var loadingTask: Task<Void, Never>?
1315

1416
var body: some View {
1517
Group {
1618
if selectedImage != nil {
17-
if let loadedImage = loadedImage {
19+
if let loadedImage = loadedImage, currentLoadingURL == selectedImage {
1820
ScrollView([.horizontal, .vertical]) {
1921
Image(nsImage: loadedImage)
2022
.resizable()
@@ -41,26 +43,50 @@ struct PaneImageViewer: View {
4143
.background(Color(NSColor.controlBackgroundColor))
4244
}
4345
}
44-
// Load when the view appears and whenever the selectedImage changes.
45-
// .task(id:) runs initially and on every change of the id, so it
46-
// covers both the initial-selection case and subsequent changes.
47-
.task(id: selectedImage) {
46+
.onChange(of: selectedImage) { _, newValue in
47+
loadImage(from: newValue)
48+
}
49+
.onAppear {
4850
loadImage(from: selectedImage)
4951
}
5052
}
5153

5254
private func loadImage(from url: URL?) {
53-
// Clear current image immediately to show loading state.
54-
// Ensure state changes happen on the main actor.
55-
DispatchQueue.main.async {
56-
self.loadedImage = nil
55+
// Cancel any existing loading task
56+
loadingTask?.cancel()
57+
58+
guard let url = url else {
59+
loadedImage = nil
60+
currentLoadingURL = nil
61+
return
62+
}
63+
64+
// Don't reload if it's the exact same URL and we already have the image loaded for it
65+
if currentLoadingURL == url && loadedImage != nil {
66+
return
5767
}
5868

59-
guard let url = url else { return }
69+
// Set the new loading URL and clear image if switching URLs
70+
let previousURL = currentLoadingURL
71+
currentLoadingURL = url
72+
73+
// Clear the loaded image if we're switching to a different URL
74+
if previousURL != url {
75+
loadedImage = nil
76+
}
77+
78+
loadingTask = Task {
79+
let image = await withTaskCancellationHandler {
80+
return await Task.detached(priority: .userInitiated) {
81+
NSImage(contentsOf: url)
82+
}.value
83+
} onCancel: {
84+
// Handle cancellation if needed
85+
}
6086

61-
DispatchQueue.global(qos: .userInitiated).async {
62-
if let image = NSImage(contentsOf: url) {
63-
DispatchQueue.main.async {
87+
// Only update if this task wasn't cancelled and we're still loading the same URL
88+
if !Task.isCancelled && currentLoadingURL == url {
89+
await MainActor.run {
6490
self.loadedImage = image
6591
}
6692
}

0 commit comments

Comments
 (0)