// // FullScreenImageView.swift // SimpleX (iOS) // // Created by Evgeny on 08/10/2022. // Copyright © 2022 SimpleX Chat. All rights reserved. // import SwiftUI import SimpleXChat import SwiftyGif struct FullScreenImageView: View { @EnvironmentObject var m: ChatModel @State var chatItem: ChatItem @State var image: UIImage @Binding var showView: Bool @State var scrollProxy: ScrollViewProxy? @State private var showNext = false @State private var nextImage: UIImage? @State private var scrolling = false @State private var offset: CGFloat = 0 @State private var nextOffset: CGFloat = 0 var body: some View { GeometryReader(content: imageScrollView) } func imageScrollView(_ g: GeometryProxy) -> some View { ZStack { Color.black.edgesIgnoringSafeArea(.all) if showNext, let nextImage = nextImage { imageView(image).offset(x: offset) imageView(nextImage).offset(x: offset + nextOffset) } else { ZoomableScrollView { imageView(image) } } } .onTapGesture { showView = false } .gesture( DragGesture(minimumDistance: 80) .onChanged { gesture in let t = gesture.translation let w = abs(t.width) if t.height > 60 && t.height > w * 2 { showView = false if let proxy = scrollProxy { proxy.scrollTo(chatItem.viewId) } } else if w > 60 && w > abs(t.height) * 2 && !scrolling { let previous = t.width > 0 scrolling = true if let item = m.nextChatItemData(chatItem.id, previous: previous, map: chatItemImage) { var img: UIImage (chatItem, img) = item nextImage = img let s = g.size.width var toOffset: CGFloat (toOffset, nextOffset) = previous ? (s, -s) : (-s, s) showNext = true withAnimation(.easeIn(duration: 0.2)) { offset = toOffset } DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { image = img showNext = false offset = 0 } } } } .onEnded { _ in scrolling = false } ) } private func imageView(_ img: UIImage) -> some View { ZStack { Color.black if img.imageData == nil { Image(uiImage: img) .resizable() .scaledToFit() } else { SwiftyGif(image: img) .scaledToFit() } } } private func chatItemImage(_ ci: ChatItem) -> (ChatItem, UIImage)? { if case .image = ci.content.msgContent, let img = getLoadedImage(ci.file) { return (ci, img) } return nil } }