diff --git a/AppliverySDK/Applivery/Modules/Screenshoot/Screens/ScreenshootPreviewScreen.swift b/AppliverySDK/Applivery/Modules/Screenshoot/Screens/ScreenshootPreviewScreen.swift index d7d5cb8..910437f 100644 --- a/AppliverySDK/Applivery/Modules/Screenshoot/Screens/ScreenshootPreviewScreen.swift +++ b/AppliverySDK/Applivery/Modules/Screenshoot/Screens/ScreenshootPreviewScreen.swift @@ -28,6 +28,13 @@ struct ScreenshootPreviewScreen: View { } Divider() TextEditor(text: $description) + .overlay(alignment: .topLeading, content: { + if description.isEmpty { + Text("Type Here ...") + .foregroundColor(.gray) + .padding(.top, 6) + } + }) .frame(maxHeight: .infinity) .lineLimit(0) .focused($focused) @@ -51,7 +58,7 @@ struct ScreenshootPreviewScreen: View { ToolbarItem(placement: .topBarTrailing) { Button(action: { - + screenshot = viewModel.saveDrawing(image: screenshot ?? UIImage(), lines: imageLines) }, label: { Image(systemName: "location.fill") .foregroundColor(.blue) diff --git a/AppliverySDK/Applivery/Modules/Screenshoot/Screens/VideoPreviewScreen.swift b/AppliverySDK/Applivery/Modules/Screenshoot/Screens/VideoPreviewScreen.swift index 4339105..670524f 100644 --- a/AppliverySDK/Applivery/Modules/Screenshoot/Screens/VideoPreviewScreen.swift +++ b/AppliverySDK/Applivery/Modules/Screenshoot/Screens/VideoPreviewScreen.swift @@ -28,6 +28,13 @@ struct VideoPreviewScreen: View { } Divider() TextEditor(text: $description) + .overlay(alignment: .topLeading, content: { + if description.isEmpty { + Text("Type Here ...") + .foregroundColor(.gray) + .padding(.top, 6) + } + }) .frame(maxHeight: .infinity) .lineLimit(0) .focused($focused) diff --git a/AppliverySDK/Applivery/Modules/Screenshoot/ViewModel/ScreenshootViewModel.swift b/AppliverySDK/Applivery/Modules/Screenshoot/ViewModel/ScreenshootViewModel.swift index d5468f0..d614dc9 100644 --- a/AppliverySDK/Applivery/Modules/Screenshoot/ViewModel/ScreenshootViewModel.swift +++ b/AppliverySDK/Applivery/Modules/Screenshoot/ViewModel/ScreenshootViewModel.swift @@ -33,4 +33,29 @@ final class ScreenshootViewModel { } } } + + func saveDrawing(image: UIImage, lines: [Line]) -> UIImage? { + UIGraphicsBeginImageContextWithOptions(image.size, false, image.scale) + guard let context = UIGraphicsGetCurrentContext() else { + UIGraphicsEndImageContext() + return nil + } + + image.draw(at: .zero) + + for line in lines { + context.setStrokeColor(line.color.cgColor ?? CGColor(red: 1, green: 1, blue: 1, alpha: 1)) + context.setLineWidth(line.lineWith) + context.setLineCap(.round) + + let cgPath = line.path.cgPath + + context.addPath(cgPath) + context.drawPath(using: .fillStroke) + } + + let newImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + return newImage + } } diff --git a/AppliverySDK/Applivery/Modules/Screenshoot/Views/EditScreenshotView.swift b/AppliverySDK/Applivery/Modules/Screenshoot/Views/EditScreenshotView.swift index 1445c8c..6a590af 100644 --- a/AppliverySDK/Applivery/Modules/Screenshoot/Views/EditScreenshotView.swift +++ b/AppliverySDK/Applivery/Modules/Screenshoot/Views/EditScreenshotView.swift @@ -10,7 +10,7 @@ import SwiftUI struct Line { var path: Path = Path() var color: Color = .red - var lineWith: Double = 1.0 + var lineWith: Double = 2.0 } struct EditScreenshotView: View { @@ -19,29 +19,29 @@ struct EditScreenshotView: View { @Binding var lines: [Line] @State private var currentLine: Line = Line() @State private var selectedColor: Color = .red + @State private var selectedStroke: Double = 2.0 @State private var editMode = false var body: some View { VStack { Spacer() drawedImage - VStack(spacing: 0) { - if editMode { - ColorPicker("Color", selection: $selectedColor) - } else { - ColorPicker("Color", selection: $selectedColor) - .hidden() - } - topBarView + VStack(spacing: 12) { + + bottomBarView } + .padding() } - .onChange(of: selectedColor, perform: { value in - currentLine.color = value + .overlay(alignment: .bottom, content: { + if editMode { + editTools + .padding(.bottom, 72) + } }) .animation(.easeIn, value: editMode) } - var topBarView: some View { + var bottomBarView: some View { HStack { Button(action: { dismiss.callAsFunction() @@ -73,34 +73,34 @@ struct EditScreenshotView: View { Spacer() Button(action: { - saveDrawing() + dismiss.callAsFunction() }, label: { Image(systemName: "checkmark") - .foregroundColor(.blue) + .foregroundColor(lines.isEmpty ? .gray : .blue) .rotationEffect(.degrees(10)) }) + .disabled(lines.isEmpty) } - .padding() } var drawedImage: some View { ZStack { Image(uiImage: screenshot ?? UIImage()) .resizable() - .scaledToFit() Canvas { context, size in for line in lines { context.stroke(line.path, with: .color(line.color), lineWidth: line.lineWith) } - context.stroke(currentLine.path, with: .color(selectedColor), lineWidth: currentLine.lineWith) + + context.stroke(currentLine.path, with: .color(currentLine.color), lineWidth: currentLine.lineWith) } .gesture(dragGesture) } } var dragGesture: some Gesture { - DragGesture(minimumDistance: 0, coordinateSpace: .local) + DragGesture(minimumDistance: 0) .onChanged { value in if editMode { currentLine.path.addLine(to: value.location) @@ -108,41 +108,23 @@ struct EditScreenshotView: View { } .onEnded { _ in lines.append(currentLine) - currentLine = Line() + currentLine = Line(path: Path(), color: selectedColor, lineWith: selectedStroke) } } - func saveDrawing() { - guard let baseImage = screenshot else { return } - - // Crear un renderizador con el tamaño de la imagen - let renderer = UIGraphicsImageRenderer(size: baseImage.size) - - let transformedImage = renderer.image { context in - baseImage.draw(at: .zero) - - // Dibujar las líneas en la imagen - let scaleX = baseImage.size.width / UIScreen.main.bounds.width - let scaleY = baseImage.size.height / UIScreen.main.bounds.height - -// let firstLineStart = CGPoint(x: baseImage.size.width * 0.1, y: baseImage.size.height * 0.1) -// let firstLineEnd = CGPoint(x: baseImage.size.width * 0.9, y: baseImage.size.height * 0.1) -// context.cgContext.move(to: firstLineStart) -// context.cgContext.addLine(to: firstLineEnd) -// context.cgContext.strokePath() - - for line in lines { - let path = line.path - let transformedPath = path.applying(CGAffineTransform(scaleX: scaleX, y: scaleY)) - context.cgContext.move(to: line.path.boundingRect.origin) - context.cgContext.addLine(to: line.path.currentPoint ?? CGPoint()) - context.cgContext.setStrokeColor(UIColor(line.color).cgColor) - context.cgContext.setLineWidth(line.lineWith) - context.cgContext.strokePath() - } + var editTools: some View { + HStack { + Slider(value: $selectedStroke, in: 2...10, step: 0.1) + .onChange(of: selectedStroke, perform: { newWith in + currentLine = Line(color: currentLine.color, lineWith: newWith) + }) + ColorPicker("", selection: $selectedColor) + .onChange(of: selectedColor, perform: { newColor in + currentLine = Line(color: newColor, lineWith: currentLine.lineWith) + }) } - - self.screenshot = transformedImage + .background(.white) + .padding(.horizontal, 100) } } diff --git a/AppliverySDK/Applivery/Modules/Screenshoot/Views/Rows/VideoPreviewRow.swift b/AppliverySDK/Applivery/Modules/Screenshoot/Views/Rows/VideoPreviewRow.swift index dfe6d4e..274d4b9 100644 --- a/AppliverySDK/Applivery/Modules/Screenshoot/Views/Rows/VideoPreviewRow.swift +++ b/AppliverySDK/Applivery/Modules/Screenshoot/Views/Rows/VideoPreviewRow.swift @@ -59,7 +59,10 @@ struct VideoPreviewRow: View { RoundedRectangle(cornerRadius: 4) .stroke(Color.black, lineWidth: 1) ) - .fullScreenCover(isPresented: $editScreenshootSheetIsPresented, content: { + .sheet(isPresented: $editScreenshootSheetIsPresented, content: { + if let videoURL { + ViedeoPlayerView(videoURL: videoURL) + } }) } diff --git a/AppliverySDK/Applivery/Modules/Screenshoot/Views/ViedeoPlayerView.swift b/AppliverySDK/Applivery/Modules/Screenshoot/Views/ViedeoPlayerView.swift new file mode 100644 index 0000000..140af0a --- /dev/null +++ b/AppliverySDK/Applivery/Modules/Screenshoot/Views/ViedeoPlayerView.swift @@ -0,0 +1,41 @@ +// +// ViedeoPlayerView.swift +// +// +// Created by Fran Alarza on 13/9/24. +// + +import SwiftUI +import AVKit +import AVFoundation + +struct ViedeoPlayerView: View { + @Environment(\.dismiss) var dismiss + let videoURL: URL + + var body: some View { + VideoPlayerViewRepresentable(videoURL: videoURL) + .edgesIgnoringSafeArea(.all) + } +} + +#Preview { + ViedeoPlayerView(videoURL: URL(string: "https://www.example.com/video.mp4")!) +} + +struct VideoPlayerViewRepresentable: UIViewControllerRepresentable { + + var videoURL: URL + + func makeUIViewController(context: Context) -> AVPlayerViewController { + let playerViewController = AVPlayerViewController() + let player = AVPlayer(url: videoURL) + playerViewController.player = player + player.play() + return playerViewController + } + + func updateUIViewController(_ uiViewController: AVPlayerViewController, context: Context) { + // No se necesita actualizar nada + } +}