diff --git a/submodules/Camera/Sources/Camera.swift b/submodules/Camera/Sources/Camera.swift index 5596929159..7656396f04 100644 --- a/submodules/Camera/Sources/Camera.swift +++ b/submodules/Camera/Sources/Camera.swift @@ -145,13 +145,13 @@ private final class CameraContext { var ciImage = CIImage(cvImageBuffer: pixelBuffer) let size = ciImage.extent.size if mirror { - var transform = CGAffineTransformMakeScale(-1.0, 1.0) - transform = CGAffineTransformTranslate(transform, size.width, 0.0) + var transform = CGAffineTransformMakeScale(1.0, -1.0) + transform = CGAffineTransformTranslate(transform, 0.0, -size.height) ciImage = ciImage.transformed(by: transform) } ciImage = ciImage.clampedToExtent().applyingGaussianBlur(sigma: 40.0).cropped(to: CGRect(origin: .zero, size: size)) if let cgImage = self.cameraImageContext.createCGImage(ciImage, from: ciImage.extent) { - let uiImage = UIImage(cgImage: cgImage, scale: 1.0, orientation: additional ? .up : .right) + let uiImage = UIImage(cgImage: cgImage, scale: 1.0, orientation: .right) if additional { CameraSimplePreviewView.saveAdditionalLastStateImage(uiImage) } else { @@ -352,11 +352,11 @@ private final class CameraContext { } else { self.configure { self.mainDeviceContext.invalidate() - self.mainDeviceContext = CameraDeviceContext(session: self.session, exclusive: true) - self.mainDeviceContext.configure(position: .back, previewView: self.simplePreviewView, audio: self.initialConfiguration.audio, photo: self.initialConfiguration.photo, metadata: self.initialConfiguration.metadata) - self.additionalDeviceContext?.invalidate() self.additionalDeviceContext = nil + + self.mainDeviceContext = CameraDeviceContext(session: self.session, exclusive: true) + self.mainDeviceContext.configure(position: .back, previewView: self.simplePreviewView, audio: self.initialConfiguration.audio, photo: self.initialConfiguration.photo, metadata: self.initialConfiguration.metadata) } self.mainDeviceContext.output.processSampleBuffer = { [weak self] sampleBuffer, pixelBuffer, connection in guard let self else { diff --git a/submodules/Camera/Sources/CameraPreviewView.swift b/submodules/Camera/Sources/CameraPreviewView.swift index c68f6d16a9..7f62f949f4 100644 --- a/submodules/Camera/Sources/CameraPreviewView.swift +++ b/submodules/Camera/Sources/CameraPreviewView.swift @@ -42,17 +42,46 @@ public class CameraSimplePreviewView: UIView { } } + private let additional: Bool + private var previewingDisposable: Disposable? private let placeholderView = UIImageView() + public init(frame: CGRect, additional: Bool) { + self.additional = additional + super.init(frame: frame) self.videoPreviewLayer.videoGravity = .resizeAspectFill + self.placeholderView.alpha = 0.0 self.placeholderView.contentMode = .scaleAspectFill self.placeholderView.image = additional ? CameraSimplePreviewView.lastAdditionalStateImage() : CameraSimplePreviewView.lastStateImage() self.addSubview(self.placeholderView) + self.resetPlaceholder() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + deinit { + self.previewingDisposable?.dispose() + } + + public override func layoutSubviews() { + super.layoutSubviews() + + self.placeholderView.frame = self.bounds.insetBy(dx: -1.0, dy: -1.0) + } + + public func resetPlaceholder() { + guard self.placeholderView.alpha == 0.0 else { + return + } + self.placeholderView.image = self.additional ? CameraSimplePreviewView.lastAdditionalStateImage() : CameraSimplePreviewView.lastStateImage() + self.placeholderView.alpha = 1.0 if #available(iOS 13.0, *) { self.previewingDisposable = (self.isPreviewing |> filter { $0 } @@ -71,20 +100,6 @@ public class CameraSimplePreviewView: UIView { } } - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - deinit { - self.previewingDisposable?.dispose() - } - - public override func layoutSubviews() { - super.layoutSubviews() - - self.placeholderView.frame = self.bounds.insetBy(dx: -1.0, dy: -1.0) - } - private var _videoPreviewLayer: AVCaptureVideoPreviewLayer? var videoPreviewLayer: AVCaptureVideoPreviewLayer { if let layer = self._videoPreviewLayer { diff --git a/submodules/TelegramUI/Components/CameraScreen/Sources/CameraScreen.swift b/submodules/TelegramUI/Components/CameraScreen/Sources/CameraScreen.swift index 6836895cfd..9c3f4aa289 100644 --- a/submodules/TelegramUI/Components/CameraScreen/Sources/CameraScreen.swift +++ b/submodules/TelegramUI/Components/CameraScreen/Sources/CameraScreen.swift @@ -1116,7 +1116,7 @@ public class CameraScreen: ViewController { let previousPosition = self.cameraPosition self.cameraPosition = state.position self.isDualCamEnabled = state.isDualCamEnabled - + if self.isDualCamEnabled && previousPosition != state.position, let additionalPreviewView = self.additionalPreviewView { if state.position == .front { additionalPreviewView.superview?.sendSubviewToBack(additionalPreviewView) @@ -1600,7 +1600,7 @@ public class CameraScreen: ViewController { transition.setFrame(view: self.previewBlurView, frame: CGRect(origin: .zero, size: previewFrame.size)) - if let additionalPreviewView = self.currentAdditionalPreviewView { + if let additionalPreviewView = self.currentAdditionalPreviewView as? CameraSimplePreviewView { additionalPreviewView.layer.cornerRadius = 80.0 var origin: CGPoint @@ -1632,7 +1632,11 @@ public class CameraScreen: ViewController { } let additionalPreviewFrame = CGRect(origin: origin, size: CGSize(width: 160.0, height: 160.0)) - transition.setPosition(view: additionalPreviewView, position: additionalPreviewFrame.center) + transition.setPosition(view: additionalPreviewView, position: additionalPreviewFrame.center, completion: { _ in + if !self.isDualCamEnabled { + additionalPreviewView.resetPlaceholder() + } + }) transition.setBounds(view: additionalPreviewView, bounds: CGRect(origin: .zero, size: additionalPreviewFrame.size)) transition.setScale(view: additionalPreviewView, scale: self.isDualCamEnabled ? 1.0 : 0.1) diff --git a/submodules/TelegramUI/Components/MediaEditor/Sources/Drawing/DrawingStickerEntity.swift b/submodules/TelegramUI/Components/MediaEditor/Sources/Drawing/DrawingStickerEntity.swift index 7ac2d4f84c..9aaa6a1334 100644 --- a/submodules/TelegramUI/Components/MediaEditor/Sources/Drawing/DrawingStickerEntity.swift +++ b/submodules/TelegramUI/Components/MediaEditor/Sources/Drawing/DrawingStickerEntity.swift @@ -4,6 +4,14 @@ import Display import AccountContext import TelegramCore +private func entitiesPath() -> String { + return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] + "/mediaEntities" +} + +private func fullEntityMediaPath(_ path: String) -> String { + return NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] + "/mediaEntities/" + path +} + public final class DrawingStickerEntity: DrawingEntity, Codable { public enum Content: Equatable { case file(TelegramMediaFile) @@ -36,9 +44,9 @@ public final class DrawingStickerEntity: DrawingEntity, Codable { private enum CodingKeys: String, CodingKey { case uuid case file - case image + case imagePath case videoPath - case videoImage + case videoImagePath case referenceDrawingSize case position case scale @@ -101,11 +109,11 @@ public final class DrawingStickerEntity: DrawingEntity, Codable { self.uuid = try container.decode(UUID.self, forKey: .uuid) if let file = try container.decodeIfPresent(TelegramMediaFile.self, forKey: .file) { self.content = .file(file) - } else if let imageData = try container.decodeIfPresent(Data.self, forKey: .image), let image = UIImage(data: imageData) { + } else if let imagePath = try container.decodeIfPresent(String.self, forKey: .imagePath), let image = UIImage(contentsOfFile: fullEntityMediaPath(imagePath)) { self.content = .image(image) } else if let videoPath = try container.decodeIfPresent(String.self, forKey: .videoPath) { var imageValue: UIImage? - if let imageData = try container.decodeIfPresent(Data.self, forKey: .image), let image = UIImage(data: imageData) { + if let imagePath = try container.decodeIfPresent(String.self, forKey: .videoImagePath), let image = UIImage(contentsOfFile: fullEntityMediaPath(imagePath)) { imageValue = image } self.content = .video(videoPath, imageValue) @@ -126,10 +134,22 @@ public final class DrawingStickerEntity: DrawingEntity, Codable { case let .file(file): try container.encode(file, forKey: .file) case let .image(image): - try container.encodeIfPresent(image.pngData(), forKey: .image) + let imagePath = "\(self.uuid).png" + let fullImagePath = fullEntityMediaPath(imagePath) + if let imageData = image.pngData() { + try? FileManager.default.createDirectory(atPath: entitiesPath(), withIntermediateDirectories: true) + try? imageData.write(to: URL(fileURLWithPath: fullImagePath)) + try container.encodeIfPresent(imagePath, forKey: .imagePath) + } case let .video(path, image): try container.encode(path, forKey: .videoPath) - try container.encodeIfPresent(image?.jpegData(compressionQuality: 0.87), forKey: .videoImage) + let imagePath = "\(self.uuid).jpg" + let fullImagePath = fullEntityMediaPath(imagePath) + if let imageData = image?.jpegData(compressionQuality: 0.87) { + try? FileManager.default.createDirectory(atPath: entitiesPath(), withIntermediateDirectories: true) + try? imageData.write(to: URL(fileURLWithPath: fullImagePath)) + try container.encodeIfPresent(imagePath, forKey: .videoImagePath) + } } try container.encode(self.referenceDrawingSize, forKey: .referenceDrawingSize) try container.encode(self.position, forKey: .position) diff --git a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift index 963c6cf81a..6cf90ae23f 100644 --- a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift +++ b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift @@ -3667,6 +3667,17 @@ final class PrivacyButtonComponent: CombinedComponent { context.add(text .position(CGPoint(x: backgroundSize.width / 2.0 + 7.0, y: backgroundSize.height / 2.0)) + .update(Transition.Update { _, view, _ in + if let snapshot = view.snapshotView(afterScreenUpdates: false) { + let transition = Transition(animation: .curve(duration: 0.2, curve: .easeInOut)) + view.superview?.addSubview(snapshot) + transition.setAlpha(view: snapshot, alpha: 0.0, completion: { [weak snapshot] _ in + snapshot?.removeFromSuperview() + }) + snapshot.frame = view.frame + transition.animateAlpha(view: view, from: 0.0, to: 1.0) + } + }) ) return backgroundSize