diff --git a/damus.xcodeproj/project.pbxproj b/damus.xcodeproj/project.pbxproj index cdfe468f..9dac622c 100644 --- a/damus.xcodeproj/project.pbxproj +++ b/damus.xcodeproj/project.pbxproj @@ -138,6 +138,7 @@ 4CEE2AF9280B2EAC00AB5EEF /* PowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CEE2AF8280B2EAC00AB5EEF /* PowView.swift */; }; 4CEE2B02280B39E800AB5EEF /* EventActionBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CEE2B01280B39E800AB5EEF /* EventActionBar.swift */; }; 4FE60CDD295E1C5E00105A1F /* Wallet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FE60CDC295E1C5E00105A1F /* Wallet.swift */; }; + 6439E014296790CF0020672B /* ProfileZoomView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6439E013296790CF0020672B /* ProfileZoomView.swift */; }; 64FBD06F296255C400D9D3B2 /* Theme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64FBD06E296255C400D9D3B2 /* Theme.swift */; }; 6C7DE41F2955169800E66263 /* Vault in Frameworks */ = {isa = PBXBuildFile; productRef = 6C7DE41E2955169800E66263 /* Vault */; }; BA693074295D649800ADDB87 /* UserSettingsStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA693073295D649800ADDB87 /* UserSettingsStore.swift */; }; @@ -331,6 +332,7 @@ 4CEE2AF8280B2EAC00AB5EEF /* PowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PowView.swift; sourceTree = ""; }; 4CEE2B01280B39E800AB5EEF /* EventActionBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventActionBar.swift; sourceTree = ""; }; 4FE60CDC295E1C5E00105A1F /* Wallet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Wallet.swift; sourceTree = ""; }; + 6439E013296790CF0020672B /* ProfileZoomView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileZoomView.swift; sourceTree = ""; }; 64FBD06E296255C400D9D3B2 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = ""; }; BA693073295D649800ADDB87 /* UserSettingsStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSettingsStore.swift; sourceTree = ""; }; BAB68BEC29543FA3007BA466 /* SelectWalletView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectWalletView.swift; sourceTree = ""; }; @@ -482,8 +484,8 @@ E990020E2955F837003BBC5A /* EditMetadataView.swift */, 3169CAE4294E699400EE4006 /* Empty Views */, 4CEE2B01280B39E800AB5EEF /* EventActionBar.swift */, - 4CEE2AF0280B216B00AB5EEF /* EventDetailView.swift */, 4C75EFB82804A2740006080F /* EventView.swift */, + 4CEE2AF0280B216B00AB5EEF /* EventDetailView.swift */, 4C3AC79E2833115300E1F516 /* FollowButtonView.swift */, 4C3AC79C2833036D00E1F516 /* FollowingView.swift */, 4C90BD17283A9EE5008EE7EF /* LoginView.swift */, @@ -512,6 +514,7 @@ 4C0A3F96280F8E02000448DE /* ThreadView.swift */, 4CA2EF9F280E37AC0044ACD8 /* TimelineView.swift */, 4CB55EF4295E679D007FD187 /* UserRelaysView.swift */, + 6439E013296790CF0020672B /* ProfileZoomView.swift */, ); path = Views; sourceTree = ""; @@ -879,6 +882,7 @@ 4C5F9114283D694D0052CD1C /* FollowTarget.swift in Sources */, 4CB8838629656C8B00DC99E7 /* NIP05.swift in Sources */, 4C5C7E6A284EDE2E00A22DF5 /* SearchResultsView.swift in Sources */, + 6439E014296790CF0020672B /* ProfileZoomView.swift in Sources */, 4CE6DF1627F8DEBF00C66700 /* RelayConnection.swift in Sources */, 4C3BEFD6281D995700B3DE84 /* ActionBarModel.swift in Sources */, 4C363AA428296DEE006E126D /* SearchModel.swift in Sources */, diff --git a/damus/Components/ImageCarousel.swift b/damus/Components/ImageCarousel.swift index ff557317..a2796f5c 100644 --- a/damus/Components/ImageCarousel.swift +++ b/damus/Components/ImageCarousel.swift @@ -64,9 +64,50 @@ struct ImageContextMenuModifier: ViewModifier { } } -struct ImageViewer: View { +struct ImageView: View { let urls: [URL] + @Environment(\.presentationMode) var presentationMode + //let pubkey: String + //let profiles: Profiles + + @GestureState private var scaleState: CGFloat = 1 + @GestureState private var offsetState = CGSize.zero + + @State private var offset = CGSize.zero + @State private var scale: CGFloat = 1 + + func resetStatus(){ + self.offset = CGSize.zero + self.scale = 1 + } + + var zoomGesture: some Gesture { + MagnificationGesture() + .updating($scaleState) { currentState, gestureState, _ in + gestureState = currentState + } + .onEnded { value in + scale *= value + } + } + + var dragGesture: some Gesture { + DragGesture() + .updating($offsetState) { currentState, gestureState, _ in + gestureState = currentState.translation + }.onEnded { value in + offset.height += value.translation.height + offset.width += value.translation.width + } + } + + var doubleTapGesture : some Gesture { + TapGesture(count: 2).onEnded { value in + resetStatus() + } + } + private struct ImageHandler: ImageModifier { @Binding var handler: UIImage? @@ -86,30 +127,61 @@ struct ImageViewer: View { } var body: some View { - TabView { - ForEach(urls, id: \.absoluteString) { url in - VStack{ - Text(url.lastPathComponent) - - KFAnimatedImage(url) - .configure { view in - view.framePreloadCount = 3 - } - .cacheOriginalImage() - .imageModifier(ImageHandler(handler: $image)) - .loadDiskFileSynchronously() - .scaleFactor(UIScreen.main.scale) - .fade(duration: 0.1) - .aspectRatio(contentMode: .fit) - .tabItem { - Text(url.absoluteString) - } - .id(url.absoluteString) - .modifier(ImageContextMenuModifier(url: url, image: image, showShareSheet: $showShareSheet)) - .sheet(isPresented: $showShareSheet) { - ShareSheet(activityItems: [url]) - } - + ZStack(alignment: .topLeading) { + Color("DamusDarkGrey") // Or Color("DamusBlack") + .edgesIgnoringSafeArea(.all) + + HStack() { + Button { + presentationMode.wrappedValue.dismiss() + } label: { + Image(systemName: "xmark") + .foregroundColor(.white) + .font(.largeTitle) + .frame(width: 40, height: 40) + .padding(20) + } + } + .zIndex(1) + + VStack(alignment: .center) { + //Spacer() + //.frame(height: 120) + + TabView { + ForEach(urls, id: \.absoluteString) { url in + VStack{ + //Color("DamusDarkGrey") + Text(url.lastPathComponent) + .foregroundColor(Color("DamusWhite")) + + KFAnimatedImage(url) + .configure { view in + view.framePreloadCount = 3 + } + .cacheOriginalImage() + .imageModifier(ImageHandler(handler: $image)) + .loadDiskFileSynchronously() + .scaleFactor(UIScreen.main.scale) + .fade(duration: 0.1) + .aspectRatio(contentMode: .fit) + .tabItem { + Text(url.absoluteString) + } + .id(url.absoluteString) + .modifier(ImageContextMenuModifier(url: url, image: image, showShareSheet: $showShareSheet)) + .sheet(isPresented: $showShareSheet) { + ShareSheet(activityItems: [url]) + } + //.padding(100) + .scaledToFit() + .scaleEffect(self.scale * scaleState) + .offset(x: offset.width + offsetState.width, y: offset.height + offsetState.height) + .gesture(SimultaneousGesture(zoomGesture, dragGesture)) + .gesture(doubleTapGesture) + + }.padding(.bottom, 50) // Ensure carousel appears beneath + } } } } @@ -151,8 +223,8 @@ struct ImageCarousel: View { } } .cornerRadius(10) - .sheet(isPresented: $open_sheet) { - ImageViewer(urls: urls) + .fullScreenCover(isPresented: $open_sheet) { + ImageView(urls: urls) } .frame(height: 200) .onTapGesture { @@ -164,6 +236,6 @@ struct ImageCarousel: View { struct ImageCarousel_Previews: PreviewProvider { static var previews: some View { - ImageCarousel(urls: [URL(string: "https://jb55.com/red-me.jpg")!]) + ImageCarousel(urls: [URL(string: "https://jb55.com/red-me.jpg")!,URL(string: "https://jb55.com/red-me.jpg")!]) } } diff --git a/damus/Views/ImageView.swift b/damus/Views/ImageView.swift new file mode 100644 index 00000000..ae2d9efc --- /dev/null +++ b/damus/Views/ImageView.swift @@ -0,0 +1,20 @@ +// +// ImageView.swift +// damus +// +// Created by user232838 on 1/5/23. +// + +import SwiftUI + +struct ImageView: View { + var body: some View { + Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + } +} + +struct ImageView_Previews: PreviewProvider { + static var previews: some View { + ImageView() + } +} diff --git a/damus/Views/MagnificationGestureView.swift b/damus/Views/MagnificationGestureView.swift new file mode 100644 index 00000000..62af4967 --- /dev/null +++ b/damus/Views/MagnificationGestureView.swift @@ -0,0 +1,33 @@ +// +// MagnificationGestureView.swift +// damus +// +// Created by user232838 on 1/5/23. +// + +import SwiftUI + +struct MagnificationGestureView: View { + + @GestureState var magnifyBy = 1.0 + + var magnification: some Gesture { + MagnificationGesture() + .updating($magnifyBy) { currentState, gestureState, transaction in + gestureState = currentState + } + } + + var body: some View { + Circle() + .frame(width: 100, height: 100) + .scaleEffect(magnifyBy) + .gesture(magnification) + } +} + +struct MagnificationGestureView_Previews: PreviewProvider { + static var previews: some View { + MagnificationGestureView() + } +} diff --git a/damus/Views/ProfileView.swift b/damus/Views/ProfileView.swift index 24ab8624..20dbfd40 100644 --- a/damus/Views/ProfileView.swift +++ b/damus/Views/ProfileView.swift @@ -196,9 +196,8 @@ struct ProfileView: View { .onTapGesture { is_zoomed.toggle() } - .sheet(isPresented: $is_zoomed) { - ProfilePicView(pubkey: profile.pubkey, size: zoom_size, highlight: .none, profiles: damus_state.profiles) - } + .fullScreenCover(isPresented: $is_zoomed) { + ProfileZoomView(pubkey: profile.pubkey, profiles: damus_state.profiles) } .offset(y: -(pfp_size/2.0)) // Increase if set a frame Spacer() diff --git a/damus/Views/ProfileZoomView.swift b/damus/Views/ProfileZoomView.swift new file mode 100644 index 00000000..a46cd29a --- /dev/null +++ b/damus/Views/ProfileZoomView.swift @@ -0,0 +1,95 @@ +// +// ProfileZoomView.swift +// damus +// +// Created by scoder1747 on 12/27/22. +// +import SwiftUI + +struct ProfileZoomView: View { + + @Environment(\.presentationMode) var presentationMode + let pubkey: String + let profiles: Profiles + + @GestureState private var scaleState: CGFloat = 1 + @GestureState private var offsetState = CGSize.zero + + @State private var offset = CGSize.zero + @State private var scale: CGFloat = 1 + + func resetStatus(){ + self.offset = CGSize.zero + self.scale = 1 + } + + var zoomGesture: some Gesture { + MagnificationGesture() + .updating($scaleState) { currentState, gestureState, _ in + gestureState = currentState + } + .onEnded { value in + scale *= value + } + } + + var dragGesture: some Gesture { + DragGesture() + .updating($offsetState) { currentState, gestureState, _ in + gestureState = currentState.translation + }.onEnded { value in + offset.height += value.translation.height + offset.width += value.translation.width + } + } + + var doubleTapGesture : some Gesture { + TapGesture(count: 2).onEnded { value in + resetStatus() + } + } + + var body: some View { + ZStack(alignment: .topLeading) { + Color("DamusDarkGrey") // Or Color("DamusBlack") + .edgesIgnoringSafeArea(.all) + + HStack() { + Button { + presentationMode.wrappedValue.dismiss() + } label: { + Image(systemName: "xmark") + .foregroundColor(.white) + .font(.largeTitle) + .frame(width: 40, height: 40) + .padding(20) + } + } + .zIndex(1) + + VStack(alignment: .center) { + Spacer() + .frame(height: 120) + + ProfilePicView(pubkey: pubkey, size: 200.0, highlight: .none, profiles: profiles) + .padding(100) + .scaledToFit() + .scaleEffect(self.scale * scaleState) + .offset(x: offset.width + offsetState.width, y: offset.height + offsetState.height) + .gesture(SimultaneousGesture(zoomGesture, dragGesture)) + .gesture(doubleTapGesture) + + } + } + } +} + +struct ProfileZoomView_Previews: PreviewProvider { + static let pubkey = "ca48854ac6555fed8e439ebb4fa2d928410e0eef13fa41164ec45aaaa132d846" + + static var previews: some View { + ProfileZoomView( + pubkey: pubkey, + profiles: make_preview_profiles(pubkey)) + } +}