mirror of
https://github.com/dscyrescotti/Memola.git
synced 2026-05-11 10:20:04 +02:00
feat: delete photo if it is inserted
This commit is contained in:
@@ -87,6 +87,7 @@
|
||||
ECBE529C2C1D94A4006BDB3D /* CameraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECBE529A2C1D94A4006BDB3D /* CameraView.swift */; };
|
||||
ECBE529E2C1DAB21006BDB3D /* UIImage++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECBE529D2C1DAB21006BDB3D /* UIImage++.swift */; };
|
||||
ECC995A32C1E8F2800B2699A /* PhotoItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC995A22C1E8F2800B2699A /* PhotoItem.swift */; };
|
||||
ECC995A52C1EB4CC00B2699A /* Data++.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECC995A42C1EB4CC00B2699A /* Data++.swift */; };
|
||||
ECD12A862C19EE3900B96E12 /* ElementObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECD12A852C19EE3900B96E12 /* ElementObject.swift */; };
|
||||
ECD12A8A2C19EFB000B96E12 /* Element.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECD12A892C19EFB000B96E12 /* Element.swift */; };
|
||||
ECD12A8C2C1AEAA900B96E12 /* PhotoObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECD12A8B2C1AEAA900B96E12 /* PhotoObject.swift */; };
|
||||
@@ -189,6 +190,7 @@
|
||||
ECBE529A2C1D94A4006BDB3D /* CameraView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CameraView.swift; sourceTree = "<group>"; };
|
||||
ECBE529D2C1DAB21006BDB3D /* UIImage++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage++.swift"; sourceTree = "<group>"; };
|
||||
ECC995A22C1E8F2800B2699A /* PhotoItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoItem.swift; sourceTree = "<group>"; };
|
||||
ECC995A42C1EB4CC00B2699A /* Data++.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data++.swift"; sourceTree = "<group>"; };
|
||||
ECD12A852C19EE3900B96E12 /* ElementObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementObject.swift; sourceTree = "<group>"; };
|
||||
ECD12A892C19EFB000B96E12 /* Element.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Element.swift; sourceTree = "<group>"; };
|
||||
ECD12A8B2C1AEAA900B96E12 /* PhotoObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoObject.swift; sourceTree = "<group>"; };
|
||||
@@ -514,6 +516,7 @@
|
||||
EC3565552BEFC7B300A4E0BF /* NSManagedObject++.swift */,
|
||||
EC35655B2BF0712A00A4E0BF /* Float++.swift */,
|
||||
ECBE529D2C1DAB21006BDB3D /* UIImage++.swift */,
|
||||
ECC995A42C1EB4CC00B2699A /* Data++.swift */,
|
||||
);
|
||||
path = Extensions;
|
||||
sourceTree = "<group>";
|
||||
@@ -925,6 +928,7 @@
|
||||
ECA738DE2BE610A000A4542E /* ViewPortRenderPass.swift in Sources */,
|
||||
EC7F6BEC2BE5E6E300A34A7B /* MemolaApp.swift in Sources */,
|
||||
EC2BEBF82C0F601A005DB0AF /* Node.swift in Sources */,
|
||||
ECC995A52C1EB4CC00B2699A /* Data++.swift in Sources */,
|
||||
ECA738A02BE601E400A4542E /* ViewPortVertex.swift in Sources */,
|
||||
ECD12A8A2C19EFB000B96E12 /* Element.swift in Sources */,
|
||||
EC0D14282BF7BF20009BFE5F /* ContextMenuViewModifier.swift in Sources */,
|
||||
|
||||
@@ -131,42 +131,6 @@ extension Canvas {
|
||||
func insertPhoto(at point: CGPoint, photoItem: PhotoItem) {
|
||||
graphicContext.insertPhoto(at: point, photoItem: photoItem)
|
||||
}
|
||||
|
||||
func bookmarkPhoto(of image: UIImage) -> PhotoItem? {
|
||||
guard let data = image.jpegData(compressionQuality: 1) else { return nil }
|
||||
let fileManager = FileManager.default
|
||||
guard let directory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else {
|
||||
return nil
|
||||
}
|
||||
let fileName = "\(UUID().uuidString)-\(Date.now.timeIntervalSince1970)"
|
||||
let folder = directory.appendingPathComponent(canvasID.uriRepresentation().lastPathComponent, conformingTo: .folder)
|
||||
|
||||
if folder.startAccessingSecurityScopedResource(), !fileManager.fileExists(atPath: folder.path()) {
|
||||
do {
|
||||
try fileManager.createDirectory(at: folder, withIntermediateDirectories: true)
|
||||
folder.stopAccessingSecurityScopedResource()
|
||||
} catch {
|
||||
NSLog("[Memola] - \(error.localizedDescription)")
|
||||
folder.stopAccessingSecurityScopedResource()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
let file = folder.appendingPathComponent(fileName, conformingTo: .jpeg)
|
||||
do {
|
||||
try data.write(to: file)
|
||||
} catch {
|
||||
NSLog("[Memola] - \(error.localizedDescription)")
|
||||
return nil
|
||||
}
|
||||
var photoBookmark: PhotoItem?
|
||||
do {
|
||||
let bookmark = try file.bookmarkData(options: .minimalBookmark)
|
||||
photoBookmark = PhotoItem(id: file, image: image, bookmark: bookmark)
|
||||
} catch {
|
||||
NSLog("[Memola] - \(error.localizedDescription)")
|
||||
}
|
||||
return photoBookmark
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Rendering
|
||||
|
||||
@@ -59,17 +59,6 @@ final class Photo: @unchecked Sendable, Equatable, Comparable {
|
||||
PhotoVertex(x: maxX, y: maxY, textCoord: CGPoint(x: 1, y: 1)),
|
||||
]
|
||||
}
|
||||
|
||||
func getBookmarkURL() -> URL? {
|
||||
var isStale = false
|
||||
guard let bookmark else {
|
||||
return nil
|
||||
}
|
||||
guard let bookmarkURL = try? URL(resolvingBookmarkData: bookmark, options: .withoutUI, relativeTo: nil, bookmarkDataIsStale: &isStale) else {
|
||||
return nil
|
||||
}
|
||||
return bookmarkURL
|
||||
}
|
||||
}
|
||||
|
||||
extension Photo: Drawable {
|
||||
@@ -78,7 +67,7 @@ extension Photo: Drawable {
|
||||
vertexCount = vertices.endIndex
|
||||
vertexBuffer = device.makeBuffer(bytes: vertices, length: vertexCount * MemoryLayout<PhotoVertex>.stride, options: [])
|
||||
}
|
||||
if texture == nil, let url = getBookmarkURL() {
|
||||
if texture == nil, let url = bookmark?.getBookmarkURL() {
|
||||
texture = Textures.createPhotoTexture(for: url, on: device)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,4 +112,62 @@ public class Tool: NSObject, ObservableObject {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func selectPhoto(_ image: UIImage, for canvasID: NSManagedObjectID) {
|
||||
let photoItem = bookmarkPhoto(of: image, with: canvasID)
|
||||
withAnimation {
|
||||
selectedPhotoItem = photoItem
|
||||
}
|
||||
}
|
||||
|
||||
private func bookmarkPhoto(of image: UIImage, with canvasID: NSManagedObjectID) -> PhotoItem? {
|
||||
guard let data = image.jpegData(compressionQuality: 1) else { return nil }
|
||||
let fileManager = FileManager.default
|
||||
guard let directory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else {
|
||||
return nil
|
||||
}
|
||||
let fileName = "\(UUID().uuidString)-\(Date.now.timeIntervalSince1970)"
|
||||
let folder = directory.appendingPathComponent(canvasID.uriRepresentation().lastPathComponent, conformingTo: .folder)
|
||||
|
||||
if folder.startAccessingSecurityScopedResource(), !fileManager.fileExists(atPath: folder.path()) {
|
||||
do {
|
||||
try fileManager.createDirectory(at: folder, withIntermediateDirectories: true)
|
||||
folder.stopAccessingSecurityScopedResource()
|
||||
} catch {
|
||||
NSLog("[Memola] - \(error.localizedDescription)")
|
||||
folder.stopAccessingSecurityScopedResource()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
let file = folder.appendingPathComponent(fileName, conformingTo: .jpeg)
|
||||
do {
|
||||
try data.write(to: file)
|
||||
} catch {
|
||||
NSLog("[Memola] - \(error.localizedDescription)")
|
||||
return nil
|
||||
}
|
||||
var photoBookmark: PhotoItem?
|
||||
do {
|
||||
let bookmark = try file.bookmarkData(options: .minimalBookmark)
|
||||
photoBookmark = PhotoItem(id: file, image: image, bookmark: bookmark)
|
||||
} catch {
|
||||
NSLog("[Memola] - \(error.localizedDescription)")
|
||||
}
|
||||
return photoBookmark
|
||||
}
|
||||
|
||||
func unselectPhoto() {
|
||||
guard let photoItem = selectedPhotoItem else { return }
|
||||
let fileManager = FileManager.default
|
||||
if let url = photoItem.bookmark.getBookmarkURL() {
|
||||
do {
|
||||
try fileManager.removeItem(at: url)
|
||||
} catch {
|
||||
NSLog("[Memola] - \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
withAnimation {
|
||||
selectedPhotoItem = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
18
Memola/Extensions/Data++.swift
Normal file
18
Memola/Extensions/Data++.swift
Normal file
@@ -0,0 +1,18 @@
|
||||
//
|
||||
// Data++.swift
|
||||
// Memola
|
||||
//
|
||||
// Created by Dscyre Scotti on 6/16/24.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Data {
|
||||
func getBookmarkURL() -> URL? {
|
||||
var isStale = false
|
||||
guard let bookmarkURL = try? URL(resolvingBookmarkData: self, options: .withoutUI, relativeTo: nil, bookmarkDataIsStale: &isStale) else {
|
||||
return nil
|
||||
}
|
||||
return bookmarkURL
|
||||
}
|
||||
}
|
||||
@@ -26,9 +26,7 @@ struct PhotoPreview: View {
|
||||
.cornerRadius(5)
|
||||
.overlay(alignment: .topLeading) {
|
||||
Button {
|
||||
withAnimation {
|
||||
tool.selectedPhotoItem = nil
|
||||
}
|
||||
tool.unselectPhoto()
|
||||
} label: {
|
||||
Image(systemName: "xmark.circle.fill")
|
||||
.font(.title2)
|
||||
|
||||
@@ -61,10 +61,7 @@ struct Toolbar: View {
|
||||
Task {
|
||||
let data = try? await newValue?.loadTransferable(type: Data.self)
|
||||
if let data, let image = UIImage(data: data) {
|
||||
let photoItem = canvas.bookmarkPhoto(of: image)
|
||||
withAnimation {
|
||||
tool.selectedPhotoItem = photoItem
|
||||
}
|
||||
tool.selectPhoto(image, for: canvas.canvasID)
|
||||
}
|
||||
photosPickerItem = nil
|
||||
}
|
||||
@@ -75,7 +72,7 @@ struct Toolbar: View {
|
||||
tool.selectedPhotoItem?.image
|
||||
} set: { image in
|
||||
guard let image else { return }
|
||||
tool.selectedPhotoItem = canvas.bookmarkPhoto(of: image)
|
||||
tool.selectPhoto(image, for: canvas.canvasID)
|
||||
}
|
||||
CameraView(image: image, canvas: canvas)
|
||||
.ignoresSafeArea()
|
||||
|
||||
Reference in New Issue
Block a user