diff --git a/NearDrop/AppDelegate.swift b/NearDrop/AppDelegate.swift index 58740af..62b1e2f 100644 --- a/NearDrop/AppDelegate.swift +++ b/NearDrop/AppDelegate.swift @@ -123,10 +123,12 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele } @objc func sendClipboard() { - if let fileURL = ClipboardManager.saveClipboardToTempFile() { - let sharingService = NSSharingService(named: NSSharingService.Name("com.leonboettger.neardrop.ShareExtension")) - sharingService?.perform(withItems: [fileURL]) - } + + let pasteboard = NSPasteboard.general + let clipboardString = pasteboard.string(forType: .string) ?? "" + + let sharingService = NSSharingService(named: NSSharingService.Name("com.leonboettger.neardrop.ShareExtension")) + sharingService?.perform(withItems: [clipboardString]) } @objc func openWelcomeScreen() { diff --git a/NearbyShare/NearbyConnectionManager.swift b/NearbyShare/NearbyConnectionManager.swift index 7ed70b9..63b66cd 100644 --- a/NearbyShare/NearbyConnectionManager.swift +++ b/NearbyShare/NearbyConnectionManager.swift @@ -385,12 +385,12 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb } } - public func startOutgoingTransfer(deviceID: String, delegate: ShareExtensionDelegate, urls: [URL]) { + public func startOutgoingTransfer(deviceID: String, delegate: ShareExtensionDelegate, urls: [URL], textToSend: String?) { guard let info = foundServices[deviceID] else { return } let tcp = NWProtocolTCP.Options() tcp.noDelay = true let nwconn = NWConnection(to: info.service.endpoint, using: NWParameters(tls: .none, tcp: tcp)) - let conn = OutboundNearbyConnection(connection: nwconn, id: deviceID, urlsToSend: urls) + let conn = OutboundNearbyConnection(connection: nwconn, id: deviceID, urlsToSend: urls, textToSend: textToSend) conn.delegate = self let transfer = OutgoingTransferInfo(service: info.service, device: info.device!, connection: conn, delegate: delegate) outgoingTransfers[deviceID] = transfer diff --git a/NearbyShare/OutboundNearbyConnection.swift b/NearbyShare/OutboundNearbyConnection.swift index 4914139..a0a25f9 100644 --- a/NearbyShare/OutboundNearbyConnection.swift +++ b/NearbyShare/OutboundNearbyConnection.swift @@ -15,26 +15,33 @@ import UniformTypeIdentifiers import BigInt import SwiftECC + class OutboundNearbyConnection: NearbyConnection { private var currentState: State = .initial private let urlsToSend: [URL] + private let textToSend: String? private var ukeyClientFinishMsgData: Data? private var queue: [OutgoingFileTransfer] = [] private var currentTransfer: OutgoingFileTransfer? - public var delegate: OutboundNearbyConnectionDelegate? private var totalBytesToSend: Int64 = 0 private var totalBytesSent: Int64 = 0 private var cancelled: Bool = false private var textPayloadID: Int64 = 0 + + public var delegate: OutboundNearbyConnectionDelegate? enum State { case initial, sentUkeyClientInit, sentUkeyClientFinish, sentPairedKeyEncryption, sentPairedKeyResult, sentIntroduction, sendingFiles } - init(connection: NWConnection, id: String, urlsToSend: [URL]) { + init(connection: NWConnection, id: String, urlsToSend: [URL], textToSend: String?) { + self.urlsToSend = urlsToSend + self.textToSend = textToSend + super.init(connection: connection, id: id) - if urlsToSend.count == 1 && !urlsToSend[0].isFileURL { + + if hasURL() || textToSend != nil { textPayloadID = Int64.random(in: Int64.min ... Int64.max) } } @@ -93,7 +100,9 @@ class OutboundNearbyConnection: NearbyConnection { } } catch { if case NearbyError.ukey2 = error { - } else if currentState == .sentUkeyClientInit { + // do nothing + } + else if currentState == .sentUkeyClientInit { sendUkey2Alert(type: .badMessage) } lastError = error @@ -256,7 +265,16 @@ class OutboundNearbyConnection: NearbyConnection { var introduction = Sharing_Nearby_Frame() introduction.version = .v1 introduction.v1.type = .introduction - if urlsToSend.count == 1 && !urlsToSend[0].isFileURL { + + if let textToSend = textToSend { + var meta = Sharing_Nearby_TextMetadata() + meta.type = .text + meta.textTitle = textToSend + meta.size = Int64(textToSend.utf8.count) + meta.payloadID = textPayloadID + introduction.v1.introduction.textMetadata.append(meta) + + } else if hasURL() { var meta = Sharing_Nearby_TextMetadata() meta.type = .url meta.textTitle = urlsToSend[0].host ?? "URL" @@ -313,7 +331,11 @@ class OutboundNearbyConnection: NearbyConnection { case .accept: currentState = .sendingFiles delegate?.outboundConnectionTransferAccepted(connection: self) - if urlsToSend.count == 1 && !urlsToSend[0].isFileURL { + + if let textToSend = textToSend { + try sendText(text: textToSend) + } + if hasURL() { try sendURL() } else { try sendNextFileChunk() @@ -332,9 +354,17 @@ class OutboundNearbyConnection: NearbyConnection { try sendDisconnectionAndDisconnect() } } + + private func hasURL() -> Bool { + urlsToSend.count == 1 && !urlsToSend[0].isFileURL + } private func sendURL() throws { - try sendBytesPayload(data: Data(urlsToSend[0].absoluteString.utf8), id: textPayloadID) + try sendText(text: urlsToSend[0].absoluteString) + } + + private func sendText(text: String) throws { + try sendBytesPayload(data: Data(text.utf8), id: textPayloadID) delegate?.outboundConnectionTransferFinished(connection: self) try sendDisconnectionAndDisconnect() } diff --git a/ShareExtension/ShareViewController.swift b/ShareExtension/ShareViewController.swift index 0d44148..2aa6954 100644 --- a/ShareExtension/ShareViewController.swift +++ b/ShareExtension/ShareViewController.swift @@ -12,6 +12,7 @@ import SwiftUI class ShareViewController: NSViewController, ShareExtensionDelegate { private var urls: [URL] = [] + private var textToSend: String? = nil private var foundDevices: [RemoteDeviceInfo] = [] private var chosenDevice: RemoteDeviceInfo? private var lastError: Error? @@ -47,11 +48,11 @@ class ShareViewController: NSViewController, ShareExtensionDelegate { let item = extensionContext!.inputItems[0] as! NSExtensionItem if let attachments = item.attachments { - if let text = item.attributedContentText?.string, attachments.isEmpty, let tempUrl = ClipboardManager.saveTextToTempFile(text: text) { - urls.append(tempUrl) + if let text = item.attributedContentText?.string, attachments.isEmpty { + textToSend = text DispatchQueue.main.async { - self.urlsReady() + self.zipFolderAndSetUpIcon() } } else { for attachment in attachments { @@ -67,7 +68,7 @@ class ShareViewController: NSViewController, ShareExtensionDelegate { if self.urls.count == attachments.count { DispatchQueue.main.async { - self.urlsReady() + self.zipFolderAndSetUpIcon() } } } @@ -177,7 +178,7 @@ class ShareViewController: NSViewController, ShareExtensionDelegate { } } - private func urlsReady() { + private func zipFolderAndSetUpIcon() { for url in urls { if url.isFileURL { let isDirectory = UnsafeMutablePointer.allocate(capacity: 1) @@ -212,7 +213,20 @@ class ShareViewController: NSViewController, ShareExtensionDelegate { } } - if urls.count == 1 { + if let textToSend = textToSend { + let maxLength = 50 + let cleanedText = textToSend.replacingOccurrences(of: "\n", with: " ").replacingOccurrences(of: "\r", with: "") + + if cleanedText.count > maxLength { + let index = cleanedText.index(cleanedText.startIndex, offsetBy: maxLength) + filesLabel!.stringValue = String(cleanedText[..