diff --git a/QuickDrop/AppDelegate.swift b/QuickDrop/AppDelegate.swift index ff531df..00d2f31 100644 --- a/QuickDrop/AppDelegate.swift +++ b/QuickDrop/AppDelegate.swift @@ -14,10 +14,9 @@ import SwiftUI import UserNotifications @main -class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDelegate, NSWindowDelegate, MainAppDelegate { +class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDelegate, NSWindowDelegate { private var statusItem: NSStatusItem? - private var activeIncomingTransfers: [String: TransferInfo] = [:] var welcomeWindow: NSWindow? var plusWindow: NSWindow? @@ -27,6 +26,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele private var errorAlertHandler = ErrorAlertHandler.shared private var iapManager: IAPManager? + private var receiveModel: ReceiveModel? var showsFirewallAlert = false var visibleItem: NSMenuItem? = nil @@ -65,9 +65,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele statusItem?.menu = menu statusItem?.behavior = .removalAllowed - NearbyConnectionManager.shared.mainAppDelegate = self - NearbyConnectionManager.shared.becomeVisible() - iapManager = IAPManager.sharedInstance iapManager?.startObserving() @@ -112,7 +109,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele let queue2 = DispatchQueue(label: "NetworkConnectionMonitor") hasConnectionMonitor.start(queue: queue2) - + receiveModel = ReceiveModel(controlPlusScreen: { shouldOpen in if shouldOpen { self.openPlusScreen() @@ -136,7 +133,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele welcomeWindow = nil NSApp.setActivationPolicy(.accessory) } - } + } func applicationShouldHandleReopen(_: NSApplication, hasVisibleWindows _: Bool) -> Bool { @@ -187,8 +184,15 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele let pasteboard = NSPasteboard.general let clipboardString = pasteboard.string(forType: .string) ?? "" - let sharingService = NSSharingService(named: NSSharingService.Name("com.leonboettger.neardrop.ShareExtension")) - sharingService?.perform(withItems: [clipboardString]) + if clipboardString.isEmpty { + DispatchQueue.main.async { + BezelNotification.show(messageText: "ClipboardEmpty".localized(), icon: .clipboard) + } + } + else { + let sharingService = NSSharingService(named: NSSharingService.Name("com.leonboettger.neardrop.ShareExtension")) + sharingService?.perform(withItems: [clipboardString]) + } } @@ -243,7 +247,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele log("Plus screen already open, bringing to front") return } - + log("Opening Plus screen") // Create the welcome screen SwiftUI view @@ -318,7 +322,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele } } - + // MARK: - Helper Functions private func performDeviceToDeviceCheck() { diff --git a/ShareExtension/ShareViewController.swift b/ShareExtension/ShareViewController.swift index cdf78fe..8e7050f 100644 --- a/ShareExtension/ShareViewController.swift +++ b/ShareExtension/ShareViewController.swift @@ -8,8 +8,10 @@ import Cocoa import Foundation import SwiftUI +import QRCode -class ShareViewController: NSViewController, ShareExtensionDelegate { +class ShareViewController: NSViewController, OutboundAppDelegate { + private var urls: [URL] = [] private var textToSend: String? = nil private var foundDevices: [RemoteDeviceInfo] = [] @@ -46,11 +48,12 @@ class ShareViewController: NSViewController, ShareExtensionDelegate { override func loadView() { + super.loadView() loadAttachments(with: extensionContext, loadedItems: { result in - + log("Loaded attachments: \(result)") - + self.urls = result.urls self.textToSend = result.textToSend self.filesLabel?.stringValue = result.shortDescription @@ -93,6 +96,7 @@ class ShareViewController: NSViewController, ShareExtensionDelegate { override func viewDidLoad() { + super.viewDidLoad() dicoverDevices() @@ -128,7 +132,27 @@ class ShareViewController: NSViewController, ShareExtensionDelegate { private func openQrCodeView() { if qrCodeSheetView == nil { - let contentView = SmallSheetView(type: .sendToDeviceQrCode) { + + var image: Image? = nil + + do { + let qrKey = NearbyConnectionManager.shared.generateQrCodeKey() + let qrCodeImage = try QRCode.build + .text("https://quickshare.google/qrcode#key=\(qrKey)") + .backgroundColor(CGColor(srgbRed: 1, green: 1, blue: 1, alpha: 0)) + .quietZonePixelCount(3) + .onPixels.shape(.circle()) + .eye.shape(.squircle()) + .errorCorrection(.low) + .generate.image(dimension: 1000) + + image = Image(nsImage: NSImage(cgImage: qrCodeImage, size: qrCodeImage.size)) + } + catch { + log("Error generating QR code: \(error)") + } + + let contentView = SmallSheetView(type: .sendToDeviceQrCode, dynamicQrCode: image) { self.closeQrCodeView() } @@ -161,71 +185,11 @@ class ShareViewController: NSViewController, ShareExtensionDelegate { } - private func zipFolderAndSetUpIcon() { - for url in urls { - if url.isFileURL { - let isDirectory = UnsafeMutablePointer.allocate(capacity: 1) - if FileManager.default.fileExists(atPath: url.path, isDirectory: isDirectory) && isDirectory.pointee.boolValue { - do { - let zipUrl = try createZipAtTmp(zipFilename: url.lastPathComponent, fromDirectory: url) - - let index = urls.firstIndex(of: url) - urls[index!] = zipUrl - } catch { - log("Error creating zip file: \(error)") - - DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { - log("Canceling share request because URL \(url) is a directory") - - AudioManager.playErrorSound() - let alert = NSAlert() - alert.alertStyle = .critical - - alert.messageText = "TypeNotSupported".localized() - alert.informativeText = "TypeNotSupportedDescription".localized() - alert.addButton(withTitle: "TypeNotSupportedButton".localized()) - - alert.beginSheetModal(for: self.view.window!) { _ in - let cancelError = NSError(domain: NSCocoaErrorDomain, code: NSUserCancelledError, userInfo: nil) - self.extensionContext!.cancelRequest(withError: cancelError) - } - } - - return - } - } - } - } - - 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[.. String { - if device.name.count <= 1 { - return "Android" + if let name = device.name, name.count > 1 { + return name } - return device.name + + return "Android" } }