Add support for sharing plain text

This commit is contained in:
Leon Böttger committed 2025-05-17 11:00:14 +02:00
1 parent a76983df36
commit f800975607
5 files changed
+67 -39

No files matched your search

+1 -19
View File
@@ -130,32 +130,14 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
@objc func sendClipboard() {
if let fileURL = saveClipboardToTempFile() {
if let fileURL = ClipboardManager.saveClipboardToTempFile() {
let sharingService = NSSharingService(named: NSSharingService.Name("com.leonboettger.neardrop.ShareExtension"))
sharingService?.perform(withItems: [fileURL])
}
}
func saveClipboardToTempFile() -> URL? {
let pasteboard = NSPasteboard.general
let clipboardString = pasteboard.string(forType: .string) ?? ""
let tempDirectory = FileManager.default.temporaryDirectory
let fileURL = tempDirectory.appendingPathComponent("Clipboard".localized() + ".txt")
do {
try clipboardString.write(to: fileURL, atomically: true, encoding: .utf8)
return fileURL
} catch {
log("Failed to write file: \(error)")
return nil
}
}
@objc func openWelcomeScreen() {
// Create the welcome screen SwiftUI view
let welcomeView = WelcomeScreen(openPlusScreen: openPlusScreen, checkForNetworkIssues: performDeviceToDeviceCheck)
+6
View File
@@ -34,6 +34,8 @@
69DCF49C2AB8C58500CBE2CC /* SwiftECC in Frameworks */ = {isa = PBXBuildFile; productRef = 69DCF49B2AB8C58500CBE2CC /* SwiftECC */; };
69DCF49D2AB8C9A500CBE2CC /* libNearbyShare.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 69DCF4812AB70D0600CBE2CC /* libNearbyShare.dylib */; };
69DCF49E2AB8C9A500CBE2CC /* libNearbyShare.dylib in Embed Libraries */ = {isa = PBXBuildFile; fileRef = 69DCF4812AB70D0600CBE2CC /* libNearbyShare.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
EB1358012DD87D9200B10B63 /* ClipboardManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1357FF2DD87D6E00B10B63 /* ClipboardManager.swift */; };
EB1358022DD87DE300B10B63 /* ClipboardManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1357FF2DD87D6E00B10B63 /* ClipboardManager.swift */; };
EB2B41E42DC63ACC0070FC39 /* SleepManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB2B41E32DC63AC80070FC39 /* SleepManager.swift */; };
EB2F9BFB2DA04B69004010A2 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB2F9BFA2DA04B67004010A2 /* Helpers.swift */; };
EB2F9BFE2DA05F48004010A2 /* BezelNotification in Frameworks */ = {isa = PBXBuildFile; productRef = EB2F9BFD2DA05F48004010A2 /* BezelNotification */; };
@@ -198,6 +200,7 @@
E9C8C6D22CFF66650053474D /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/ShareViewController.strings; sourceTree = "<group>"; };
E9C8C6D32CFF66650053474D /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ro; path = ro.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
E9C8C6D42CFF66650053474D /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Localizable.strings; sourceTree = "<group>"; };
EB1357FF2DD87D6E00B10B63 /* ClipboardManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClipboardManager.swift; sourceTree = "<group>"; };
EB2B41E32DC63AC80070FC39 /* SleepManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SleepManager.swift; sourceTree = "<group>"; };
EB2F9BFA2DA04B67004010A2 /* Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = "<group>"; };
EB36435F2D73A29F009CDFF8 /* AudioManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioManager.swift; sourceTree = "<group>"; };
@@ -278,6 +281,7 @@
isa = PBXGroup;
children = (
699DEBA52AB0573200115D22 /* ShareViewController.swift */,
EB1357FF2DD87D6E00B10B63 /* ClipboardManager.swift */,
EBCC27F82D80C9F70079C478 /* Zip.swift */,
EB96ED8A2D7F7CF4004B3FF1 /* QrCodeView.swift */,
691F53B92ABB70840089FD92 /* DeviceListCell.swift */,
@@ -563,6 +567,7 @@
EBCC27F92D80C9F90079C478 /* Zip.swift in Sources */,
EB7CD1462D6FB0E800CB0CB5 /* Logger.swift in Sources */,
691F53BB2ABB70840089FD92 /* DeviceListCell.swift in Sources */,
EB1358022DD87DE300B10B63 /* ClipboardManager.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -577,6 +582,7 @@
69DA9A1229E0BF5100A442DA /* AppDelegate.swift in Sources */,
EB7F54102D78E6DF00989564 /* Sidebar.swift in Sources */,
EB6F62D72D91F4AF00534EC2 /* SettingsView.swift in Sources */,
EB1358012DD87D9200B10B63 /* ClipboardManager.swift in Sources */,
EB7F54122D78E96000989564 /* TutorialView.swift in Sources */,
EB96ED8F2D7F8105004B3FF1 /* Localized.swift in Sources */,
EB7CD1452D6FB0C300CB0CB5 /* Logger.swift in Sources */,
+32
View File
@@ -0,0 +1,32 @@
//
// ClipboardManager.swift
// QuickDrop
//
// Created by Leon Böttger on 17.05.25.
//
import Foundation
import AppKit
class ClipboardManager {
static func saveClipboardToTempFile() -> URL? {
let pasteboard = NSPasteboard.general
let clipboardString = pasteboard.string(forType: .string) ?? ""
return saveTextToTempFile(text: clipboardString)
}
static func saveTextToTempFile(text: String) -> URL? {
let tempDirectory = FileManager.default.temporaryDirectory
let fileURL = tempDirectory.appendingPathComponent("Clipboard".localized() + ".txt")
do {
try text.write(to: fileURL, atomically: true, encoding: .utf8)
return fileURL
} catch {
log("Failed to write file: \(error)")
return nil
}
}
}
+6 -3
View File
@@ -13,9 +13,12 @@
SUBQUERY (
$extensionItem.attachments,
$attachment,
ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.file-url"
OR ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.url"
AND NOT (ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.folder")
(
ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO &quot;public.file-url&quot;
OR ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO &quot;public.url&quot;
OR ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO &quot;public.text&quot;
)
AND NOT (ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO &quot;public.folder&quot;)
).@count == $extensionItem.attachments.@count
).@count &gt; 0</string>
</dict>
+22 -17
View File
@@ -46,27 +46,32 @@ class ShareViewController: NSViewController, ShareExtensionDelegate{
override func loadView() {
super.loadView()
// Insert code here to customize the view
let item = self.extensionContext!.inputItems[0] as! NSExtensionItem
if let attachments = item.attachments {
for attachment in attachments as NSArray{
let provider=attachment as! NSItemProvider
provider.loadItem(forTypeIdentifier: kUTTypeURL as String) { data, err in
if let urlData=data as? Data{
if let url=URL(dataRepresentation: urlData, relativeTo: nil, isAbsolute: false){
self.urls.append(url)
if self.urls.count==attachments.count{
DispatchQueue.main.async {
self.urlsReady()
}
if let text = item.attributedContentText?.string, attachments.isEmpty, let tempUrl = ClipboardManager.saveTextToTempFile(text: text) {
self.urls.append(tempUrl)
DispatchQueue.main.async {
self.urlsReady()
}
}
else {
for attachment in attachments {
if attachment.hasItemConformingToTypeIdentifier(kUTTypeURL as String) {
attachment.loadItem(forTypeIdentifier: kUTTypeURL as String, options: nil) { data, err in
if let urlData = data as? Data,
let url = URL(dataRepresentation: urlData, relativeTo: nil, isAbsolute: false) {
self.urls.append(url)
} else if let url = data as? NSURL {
self.urls.append(url as URL)
}
}
}else if let url=data as? NSURL{
self.urls.append(url as URL)
if self.urls.count==attachments.count{
DispatchQueue.main.async {
self.urlsReady()
}
}
if self.urls.count == attachments.count {
DispatchQueue.main.async {
self.urlsReady()
}
}
}