mirror of
https://github.com/leonboe1/QuickDrop.git
synced 2026-11-11 19:11:10 +00:00
macOS: Add ability to save images/videos directly to photos app
This commit is contained in:
1 parent
4ddf39817c
commit
658a2ff28e
7 files changed
+2251
-867
No files matched your search
@@ -5,233 +5,11 @@
|
||||
"comment" : "Bundle display name",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"ar" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"ca" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"cs" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"da" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"de" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"el" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "QuickDrop"
|
||||
}
|
||||
},
|
||||
"en-AU" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"en-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"en-GB" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"es" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"es-419" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"fi" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"he" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"hi" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"hr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"hu" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"id" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"it" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"ja" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"ko" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"ms" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"nb" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"nl" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"pl" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"pt-BR" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"pt-PT" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"ro" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"ru" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"sv" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"th" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"tr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"uk" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"vi" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -239,233 +17,11 @@
|
||||
"comment" : "Bundle name",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"ar" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"ca" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"cs" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"da" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"de" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"el" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "QuickDropiOS"
|
||||
}
|
||||
},
|
||||
"en-AU" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"en-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"en-GB" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"es" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"es-419" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"fi" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"he" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"hi" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"hr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"hu" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"id" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"it" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"ja" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"ko" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"ms" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"nb" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"nl" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"pl" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"pt-BR" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"pt-PT" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"ro" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"ru" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"sv" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"th" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"tr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"uk" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"vi" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -473,233 +29,11 @@
|
||||
"comment" : "Copyright (human-readable)",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"ar" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"ca" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"cs" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"da" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"de" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"el" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"en-AU" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"en-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"en-GB" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"es" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"es-419" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"fi" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"he" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"hi" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"hr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"hu" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"id" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"it" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"ja" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"ko" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"ms" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"nb" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"nl" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"pl" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"pt-BR" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"pt-PT" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"ro" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"ru" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"sv" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"th" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"tr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"uk" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"vi" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -5,11 +5,15 @@
|
||||
// Created by Leon Böttger on 16.11.25.
|
||||
//
|
||||
|
||||
#if os(iOS)
|
||||
import UIKit
|
||||
#else
|
||||
import AppKit
|
||||
#endif
|
||||
|
||||
import Photos
|
||||
import UniformTypeIdentifiers
|
||||
|
||||
|
||||
struct PhotoManager {
|
||||
|
||||
/// Returns if there are photos or videos among the given URLs.
|
||||
@@ -44,7 +48,7 @@ struct PhotoManager {
|
||||
let exifDate = EXIFUtils.exifOriginalDate(from: sourceURL)
|
||||
imageItems.append(ImageItem(fileURL: sourceURL, creationDate: exifDate))
|
||||
} else {
|
||||
let videoDate = await getVideoCreationDate(from: sourceURL)
|
||||
let videoDate = getVideoCreationDate(from: sourceURL)
|
||||
videoItems.append(VideoItem(fileURL: sourceURL, creationDate: videoDate))
|
||||
}
|
||||
}
|
||||
@@ -96,10 +100,16 @@ struct PhotoManager {
|
||||
|
||||
// Open the Photos app
|
||||
if openPhotosOnSuccess {
|
||||
if let url = URL(string: "photos-redirect://") {
|
||||
DispatchQueue.main.async {
|
||||
DispatchQueue.main.async {
|
||||
#if os(iOS)
|
||||
if let url = URL(string: "photos-redirect://") {
|
||||
UIApplication.shared.open(url)
|
||||
}
|
||||
#else
|
||||
if let url = URL(string: "photos-navigation://album?name=recently-saved") {
|
||||
NSWorkspace.shared.open(url)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,23 +136,16 @@ struct PhotoManager {
|
||||
}
|
||||
|
||||
|
||||
private static func getVideoCreationDate(from url: URL) async -> Date? {
|
||||
private static func getVideoCreationDate(from url: URL) -> Date? {
|
||||
let asset = AVURLAsset(url: url)
|
||||
|
||||
do {
|
||||
// AVMetadataItem that typically contains an ISO‑8601 string
|
||||
guard let item = try await asset.load(.creationDate),
|
||||
let dateString = try await item.load(.stringValue) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let formatter = ISO8601DateFormatter()
|
||||
return formatter.date(from: dateString)
|
||||
}
|
||||
catch {
|
||||
log("Failed to load creation date from \(url): \(error)")
|
||||
// AVMetadataItem that typically contains an ISO‑8601 string
|
||||
guard let item = asset.creationDate,
|
||||
let dateString = item.stringValue else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let formatter = ISO8601DateFormatter()
|
||||
return formatter.date(from: dateString)
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user