diff options
| author | Fuwn <[email protected]> | 2025-02-22 06:35:52 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2025-02-22 06:35:52 -0800 |
| commit | 570a49d5c8ab326f3207e95538559b2a6f03fe59 (patch) | |
| tree | c668329a79337352dd1a730a9e055af83e7b0a0a /Sora/Other | |
| parent | feat: Development commit (diff) | |
| download | sora-testing-570a49d5c8ab326f3207e95538559b2a6f03fe59.tar.xz sora-testing-570a49d5c8ab326f3207e95538559b2a6f03fe59.zip | |
feat: Development commit
Diffstat (limited to 'Sora/Other')
| -rw-r--r-- | Sora/Other/AsyncImageWithPreview.swift | 168 |
1 files changed, 44 insertions, 124 deletions
diff --git a/Sora/Other/AsyncImageWithPreview.swift b/Sora/Other/AsyncImageWithPreview.swift index 2e29052..9cae976 100644 --- a/Sora/Other/AsyncImageWithPreview.swift +++ b/Sora/Other/AsyncImageWithPreview.swift @@ -12,138 +12,58 @@ struct AsyncImageWithPreview<Placeholder: View>: View { @State private var finalOffset: CGSize = .zero var body: some View { - GeometryReader { geometry in - AsyncImage(url: url) { image in - image - .resizable() - .scaledToFit() - .onAppear { - loadingState = finalLoadingState - } - .scaleEffect(finalScale * currentScale) - .offset( - x: finalOffset.width + currentOffset.width, - y: finalOffset.height + currentOffset.height - ) - .frame(width: geometry.size.width, height: geometry.size.height) - .position(x: geometry.size.width / 2, y: geometry.size.height / 2) - .gesture( - DragGesture() - .onChanged { value in - let translation = value.translation - let newOffset = CGSize( - width: finalOffset.width + translation.width, - height: finalOffset.height + translation.height - ) - let scale = finalScale * currentScale - let imageWidth = geometry.size.width * scale - let imageHeight = geometry.size.height * scale - let maxX = max((imageWidth - geometry.size.width) / 2, 0) - let maxY = max((imageHeight - geometry.size.height) / 2, 0) - let clampedX = min(max(newOffset.width, -maxX), maxX) - let clampedY = min(max(newOffset.height, -maxY), maxY) - - currentOffset = CGSize( - width: clampedX - finalOffset.width, - height: clampedY - finalOffset.height - ) - } - .onEnded { value in - let translation = value.translation - var newOffset = CGSize( - width: finalOffset.width + translation.width, - height: finalOffset.height + translation.height - ) - let scale = finalScale * currentScale - let imageWidth = geometry.size.width * scale - let imageHeight = geometry.size.height * scale - let maxX = max((imageWidth - geometry.size.width) / 2, 0) - let maxY = max((imageHeight - geometry.size.height) / 2, 0) - - newOffset.width = min(max(newOffset.width, -maxX), maxX) - newOffset.height = min(max(newOffset.height, -maxY), maxY) - finalOffset = newOffset - currentOffset = .zero - } - ) - .simultaneousGesture( - MagnificationGesture() - .onChanged { value in - currentScale = value - } - .onEnded { _ in - finalScale *= currentScale - currentScale = 1.0 - - let scale = finalScale - let imageWidth = geometry.size.width * scale - let imageHeight = geometry.size.height * scale - let maxX = max((imageWidth - geometry.size.width) / 2, 0) - let maxY = max((imageHeight - geometry.size.height) / 2, 0) + AsyncImage(url: url) { image in + ZoomableImageView(image: image) + .onAppear { + loadingState = finalLoadingState + } + .contextMenu { + #if os(iOS) + Button { + guard let url else { return } - finalOffset.width = min(max(finalOffset.width, -maxX), maxX) - finalOffset.height = min(max(finalOffset.height, -maxY), maxY) - } - ) - .highPriorityGesture( - TapGesture(count: 2) - .onEnded { - withAnimation { - finalScale = 1.0 - currentScale = 1.0 - finalOffset = .zero - currentOffset = .zero - } - } - ) - .contextMenu { - #if os(iOS) - Button { - guard let url else { return } - - URLSession.shared.dataTask(with: url) { data, _, _ in - guard let data, let uiImage = UIImage(data: data) else { return } + URLSession.shared.dataTask(with: url) { data, _, _ in + guard let data, let uiImage = UIImage(data: data) else { return } - UIImageWriteToSavedPhotosAlbum(uiImage, nil, nil, nil) - } - .resume() - } label: { - Label("Save Image", systemImage: "square.and.arrow.down") + UIImageWriteToSavedPhotosAlbum(uiImage, nil, nil, nil) } - #endif + .resume() + } label: { + Label("Save Image", systemImage: "square.and.arrow.down") + } + #endif - #if os(iOS) - Button { - let activityViewController = UIActivityViewController( - activityItems: [url ?? URL(string: "")!], applicationActivities: nil - ) + #if os(iOS) + Button { + let activityViewController = UIActivityViewController( + activityItems: [url ?? URL(string: "")!], applicationActivities: nil + ) - UIApplication.shared.windows.first?.rootViewController?.present( - activityViewController, animated: true - ) - } label: { - Label("Share Image", systemImage: "square.and.arrow.up") - } - #endif + UIApplication.shared.windows.first?.rootViewController?.present( + activityViewController, animated: true + ) + } label: { + Label("Share Image", systemImage: "square.and.arrow.up") + } + #endif - if let url = postURL { - Button { - #if os(iOS) - UIApplication.shared.open(url) - #else - NSWorkspace.shared.open(url) - #endif - } label: { - Label("Open in Safari", systemImage: "safari") - } + if let url = postURL { + Button { + #if os(iOS) + UIApplication.shared.open(url) + #else + NSWorkspace.shared.open(url) + #endif + } label: { + Label("Open in Safari", systemImage: "safari") } } - } placeholder: { - placeholder() - .onAppear { - loadingState = .loadingPreview - } - } + } + } placeholder: { + placeholder() + .onAppear { + loadingState = .loadingPreview + } } } |