diff --git a/1_anytime.pxd/QuickLook/Icon.webp b/1_anytime.pxd/QuickLook/Icon.webp new file mode 100644 index 0000000..0dd7baa Binary files /dev/null and b/1_anytime.pxd/QuickLook/Icon.webp differ diff --git a/1_anytime.pxd/QuickLook/Thumbnail.webp b/1_anytime.pxd/QuickLook/Thumbnail.webp new file mode 100644 index 0000000..5bdbccd Binary files /dev/null and b/1_anytime.pxd/QuickLook/Thumbnail.webp differ diff --git a/1_anytime.pxd/data/08D88BE4-4D7C-40FB-8FAA-297487D85F4F-OriginalContentSource b/1_anytime.pxd/data/08D88BE4-4D7C-40FB-8FAA-297487D85F4F-OriginalContentSource new file mode 100644 index 0000000..0352e15 Binary files /dev/null and b/1_anytime.pxd/data/08D88BE4-4D7C-40FB-8FAA-297487D85F4F-OriginalContentSource differ diff --git a/1_anytime.pxd/data/2ADDBD9F-3F82-4CC6-98E3-E045041BD996 b/1_anytime.pxd/data/2ADDBD9F-3F82-4CC6-98E3-E045041BD996 new file mode 100644 index 0000000..b377d40 Binary files /dev/null and b/1_anytime.pxd/data/2ADDBD9F-3F82-4CC6-98E3-E045041BD996 differ diff --git a/1_anytime.pxd/data/2B9BB7C0-F9C2-4F5D-81A3-54BA238F83D6 b/1_anytime.pxd/data/2B9BB7C0-F9C2-4F5D-81A3-54BA238F83D6 new file mode 100644 index 0000000..f371513 Binary files /dev/null and b/1_anytime.pxd/data/2B9BB7C0-F9C2-4F5D-81A3-54BA238F83D6 differ diff --git a/1_anytime.pxd/data/7BB7550D-3767-4A6D-872A-B41D900A2965-OriginalContentSource b/1_anytime.pxd/data/7BB7550D-3767-4A6D-872A-B41D900A2965-OriginalContentSource new file mode 100644 index 0000000..9faa7b7 Binary files /dev/null and b/1_anytime.pxd/data/7BB7550D-3767-4A6D-872A-B41D900A2965-OriginalContentSource differ diff --git a/1_anytime.pxd/data/7BC2239C-4F96-4300-AB24-138A275461D3-OriginalContentSource b/1_anytime.pxd/data/7BC2239C-4F96-4300-AB24-138A275461D3-OriginalContentSource new file mode 100644 index 0000000..f318e5a Binary files /dev/null and b/1_anytime.pxd/data/7BC2239C-4F96-4300-AB24-138A275461D3-OriginalContentSource differ diff --git a/1_anytime.pxd/data/92946977-15A4-49FF-AD2A-10B85300F334-OriginalContentSource b/1_anytime.pxd/data/92946977-15A4-49FF-AD2A-10B85300F334-OriginalContentSource new file mode 100644 index 0000000..cf2d2c4 Binary files /dev/null and b/1_anytime.pxd/data/92946977-15A4-49FF-AD2A-10B85300F334-OriginalContentSource differ diff --git a/1_anytime.pxd/data/99B3DBAB-E0AB-465E-BB81-B586F85BCADE b/1_anytime.pxd/data/99B3DBAB-E0AB-465E-BB81-B586F85BCADE new file mode 100644 index 0000000..3b5bee9 Binary files /dev/null and b/1_anytime.pxd/data/99B3DBAB-E0AB-465E-BB81-B586F85BCADE differ diff --git a/1_anytime.pxd/data/AA364677-42B5-40A8-92EC-776992CA10EF-OriginalContentSource b/1_anytime.pxd/data/AA364677-42B5-40A8-92EC-776992CA10EF-OriginalContentSource new file mode 100644 index 0000000..b21611a Binary files /dev/null and b/1_anytime.pxd/data/AA364677-42B5-40A8-92EC-776992CA10EF-OriginalContentSource differ diff --git a/1_anytime.pxd/data/BD557875-E08F-4D93-AD77-FED30D37AEF7-OriginalContentSource b/1_anytime.pxd/data/BD557875-E08F-4D93-AD77-FED30D37AEF7-OriginalContentSource new file mode 100644 index 0000000..c88a4ba Binary files /dev/null and b/1_anytime.pxd/data/BD557875-E08F-4D93-AD77-FED30D37AEF7-OriginalContentSource differ diff --git a/1_anytime.pxd/data/BF79B105-0C31-4697-901D-90CF9A7BA95F-OriginalContentSource b/1_anytime.pxd/data/BF79B105-0C31-4697-901D-90CF9A7BA95F-OriginalContentSource new file mode 100644 index 0000000..4be9ee9 Binary files /dev/null and b/1_anytime.pxd/data/BF79B105-0C31-4697-901D-90CF9A7BA95F-OriginalContentSource differ diff --git a/1_anytime.pxd/metadata.info b/1_anytime.pxd/metadata.info new file mode 100644 index 0000000..44e3cff Binary files /dev/null and b/1_anytime.pxd/metadata.info differ diff --git a/2_copy.pxd/QuickLook/Icon.webp b/2_copy.pxd/QuickLook/Icon.webp new file mode 100644 index 0000000..a31db6a Binary files /dev/null and b/2_copy.pxd/QuickLook/Icon.webp differ diff --git a/2_copy.pxd/QuickLook/Thumbnail.webp b/2_copy.pxd/QuickLook/Thumbnail.webp new file mode 100644 index 0000000..f484099 Binary files /dev/null and b/2_copy.pxd/QuickLook/Thumbnail.webp differ diff --git a/2_copy.pxd/data/08D88BE4-4D7C-40FB-8FAA-297487D85F4F-OriginalContentSource b/2_copy.pxd/data/08D88BE4-4D7C-40FB-8FAA-297487D85F4F-OriginalContentSource new file mode 100644 index 0000000..0352e15 Binary files /dev/null and b/2_copy.pxd/data/08D88BE4-4D7C-40FB-8FAA-297487D85F4F-OriginalContentSource differ diff --git a/2_copy.pxd/data/2ADDBD9F-3F82-4CC6-98E3-E045041BD996 b/2_copy.pxd/data/2ADDBD9F-3F82-4CC6-98E3-E045041BD996 new file mode 100644 index 0000000..b377d40 Binary files /dev/null and b/2_copy.pxd/data/2ADDBD9F-3F82-4CC6-98E3-E045041BD996 differ diff --git a/2_copy.pxd/data/34AC2442-4D77-49D1-A864-98FF70F1AFBA-OriginalContentSource b/2_copy.pxd/data/34AC2442-4D77-49D1-A864-98FF70F1AFBA-OriginalContentSource new file mode 100644 index 0000000..20f1d01 Binary files /dev/null and b/2_copy.pxd/data/34AC2442-4D77-49D1-A864-98FF70F1AFBA-OriginalContentSource differ diff --git a/2_copy.pxd/data/43F360B9-90D7-4DBE-8E17-406480B8D513-OriginalContentSource b/2_copy.pxd/data/43F360B9-90D7-4DBE-8E17-406480B8D513-OriginalContentSource new file mode 100644 index 0000000..94a38ec Binary files /dev/null and b/2_copy.pxd/data/43F360B9-90D7-4DBE-8E17-406480B8D513-OriginalContentSource differ diff --git a/2_copy.pxd/data/7BB7550D-3767-4A6D-872A-B41D900A2965-OriginalContentSource b/2_copy.pxd/data/7BB7550D-3767-4A6D-872A-B41D900A2965-OriginalContentSource new file mode 100644 index 0000000..9faa7b7 Binary files /dev/null and b/2_copy.pxd/data/7BB7550D-3767-4A6D-872A-B41D900A2965-OriginalContentSource differ diff --git a/2_copy.pxd/data/7BC2239C-4F96-4300-AB24-138A275461D3-OriginalContentSource b/2_copy.pxd/data/7BC2239C-4F96-4300-AB24-138A275461D3-OriginalContentSource new file mode 100644 index 0000000..f318e5a Binary files /dev/null and b/2_copy.pxd/data/7BC2239C-4F96-4300-AB24-138A275461D3-OriginalContentSource differ diff --git a/2_copy.pxd/data/92946977-15A4-49FF-AD2A-10B85300F334-OriginalContentSource b/2_copy.pxd/data/92946977-15A4-49FF-AD2A-10B85300F334-OriginalContentSource new file mode 100644 index 0000000..cf2d2c4 Binary files /dev/null and b/2_copy.pxd/data/92946977-15A4-49FF-AD2A-10B85300F334-OriginalContentSource differ diff --git a/2_copy.pxd/data/99B3DBAB-E0AB-465E-BB81-B586F85BCADE b/2_copy.pxd/data/99B3DBAB-E0AB-465E-BB81-B586F85BCADE new file mode 100644 index 0000000..3b5bee9 Binary files /dev/null and b/2_copy.pxd/data/99B3DBAB-E0AB-465E-BB81-B586F85BCADE differ diff --git a/2_copy.pxd/data/AA364677-42B5-40A8-92EC-776992CA10EF-OriginalContentSource b/2_copy.pxd/data/AA364677-42B5-40A8-92EC-776992CA10EF-OriginalContentSource new file mode 100644 index 0000000..b21611a Binary files /dev/null and b/2_copy.pxd/data/AA364677-42B5-40A8-92EC-776992CA10EF-OriginalContentSource differ diff --git a/2_copy.pxd/metadata.info b/2_copy.pxd/metadata.info new file mode 100644 index 0000000..9edc037 Binary files /dev/null and b/2_copy.pxd/metadata.info differ diff --git a/NearDrop.xcodeproj/project.pbxproj b/NearDrop.xcodeproj/project.pbxproj index 0252fad..66d67a0 100644 --- a/NearDrop.xcodeproj/project.pbxproj +++ b/NearDrop.xcodeproj/project.pbxproj @@ -40,6 +40,7 @@ 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, ); }; }; + EBD2A2172D2860C100BCB8E2 /* WelcomeScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBD2A2162D2860BE00BCB8E2 /* WelcomeScreen.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -208,6 +209,8 @@ E9C8C6D42CFF66650053474D /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Localizable.strings; sourceTree = ""; }; E9C8C6D52CFF66650053474D /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ro; path = ro.lproj/Localizable.stringsdict; sourceTree = ""; }; E9C8C6D62CFF66650053474D /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Localizable.strings; sourceTree = ""; }; + EBD2A2162D2860BE00BCB8E2 /* WelcomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeScreen.swift; sourceTree = ""; }; + EBD2A2182D28619200BCB8E2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -290,7 +293,9 @@ 69DA9A1029E0BF5100A442DA /* NearDrop */ = { isa = PBXGroup; children = ( + EBD2A2182D28619200BCB8E2 /* Info.plist */, 69DA9A1129E0BF5100A442DA /* AppDelegate.swift */, + EBD2A2162D2860BE00BCB8E2 /* WelcomeScreen.swift */, 69DA9A1329E0BF5200A442DA /* Assets.xcassets */, 69D2C33629E78DF400EC7E30 /* Localizable.stringsdict */, 69D2C32B29E77F2200EC7E30 /* Localizable.strings */, @@ -510,6 +515,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + EBD2A2172D2860C100BCB8E2 /* WelcomeScreen.swift in Sources */, 698DFB0329E362140064F247 /* NDNotificationCenterHackery.m in Sources */, 69DA9A1229E0BF5100A442DA /* AppDelegate.swift in Sources */, ); @@ -679,7 +685,9 @@ CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 6; + CURRENT_PROJECT_VERSION = 9; + DEVELOPMENT_TEAM = 92SDAWLN76; + ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = ShareExtension/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = NearDrop; @@ -690,8 +698,8 @@ "@executable_path/../../../../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 2.0.2; - PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop.ShareExtension; + MARKETING_VERSION = 2.1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.leonboettger.neardrop.ShareExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; @@ -705,7 +713,9 @@ CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 6; + CURRENT_PROJECT_VERSION = 9; + DEVELOPMENT_TEAM = 92SDAWLN76; + ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = ShareExtension/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = NearDrop; @@ -716,8 +726,8 @@ "@executable_path/../../../../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 10.15; - MARKETING_VERSION = 2.0.2; - PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop.ShareExtension; + MARKETING_VERSION = 2.1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.leonboettger.neardrop.ShareExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_EMIT_LOC_STRINGS = YES; @@ -851,7 +861,11 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 9; + DEVELOPMENT_TEAM = 92SDAWLN76; + ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = NearDrop/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = NearDrop; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; INFOPLIST_KEY_LSUIElement = YES; INFOPLIST_KEY_NSHumanReadableCopyright = ""; @@ -863,7 +877,7 @@ ); MACOSX_DEPLOYMENT_TARGET = 10.15; MARKETING_VERSION = 2.1.0; - PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop; + PRODUCT_BUNDLE_IDENTIFIER = com.leonboettger.neardrop; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = "NearDrop/NearDrop-Bridging-Header.h"; @@ -883,7 +897,11 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 9; + DEVELOPMENT_TEAM = 92SDAWLN76; + ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = NearDrop/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = NearDrop; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; INFOPLIST_KEY_LSUIElement = YES; INFOPLIST_KEY_NSHumanReadableCopyright = ""; @@ -895,7 +913,7 @@ ); MACOSX_DEPLOYMENT_TARGET = 10.15; MARKETING_VERSION = 2.1.0; - PRODUCT_BUNDLE_IDENTIFIER = me.grishka.NearDrop; + PRODUCT_BUNDLE_IDENTIFIER = com.leonboettger.neardrop; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = "NearDrop/NearDrop-Bridging-Header.h"; diff --git a/NearDrop/AppDelegate.swift b/NearDrop/AppDelegate.swift index 6f52c20..44650df 100644 --- a/NearDrop/AppDelegate.swift +++ b/NearDrop/AppDelegate.swift @@ -8,133 +8,188 @@ import Cocoa import UserNotifications import NearbyShare +import SwiftUI @main class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDelegate, MainAppDelegate{ - private var statusItem:NSStatusItem? - private var activeIncomingTransfers:[String:TransferInfo]=[:] - + private var statusItem:NSStatusItem? + private var activeIncomingTransfers:[String:TransferInfo]=[:] + + var window: NSWindow? + func applicationDidFinishLaunching(_ aNotification: Notification) { - let menu=NSMenu() - menu.addItem(withTitle: NSLocalizedString("VisibleToEveryone", value: "Visible to everyone", comment: ""), action: nil, keyEquivalent: "") - menu.addItem(withTitle: String(format: NSLocalizedString("DeviceName", value: "Device name: %@", comment: ""), arguments: [Host.current().localizedName!]), action: nil, keyEquivalent: "") - menu.addItem(NSMenuItem.separator()) - menu.addItem(withTitle: NSLocalizedString("Quit", value: "Quit NearDrop", comment: ""), action: #selector(NSApplication.terminate(_:)), keyEquivalent: "") - statusItem=NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) - statusItem?.button?.image=NSImage(named: "MenuBarIcon") - statusItem?.menu=menu - statusItem?.behavior = .removalAllowed - - let nc=UNUserNotificationCenter.current() - nc.requestAuthorization(options: [.alert, .sound]) { granted, err in - if !granted{ - DispatchQueue.main.async { - self.showNotificationsDeniedAlert() - } - } - } - nc.delegate=self - let incomingTransfersCategory=UNNotificationCategory(identifier: "INCOMING_TRANSFERS", actions: [ - UNNotificationAction(identifier: "ACCEPT", title: NSLocalizedString("Accept", comment: ""), options: UNNotificationActionOptions.authenticationRequired), - UNNotificationAction(identifier: "DECLINE", title: NSLocalizedString("Decline", comment: "")) - ], intentIdentifiers: []) - let errorsCategory=UNNotificationCategory(identifier: "ERRORS", actions: [], intentIdentifiers: []) - nc.setNotificationCategories([incomingTransfersCategory, errorsCategory]) - NearbyConnectionManager.shared.mainAppDelegate=self - NearbyConnectionManager.shared.becomeVisible() - } - - func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool { - statusItem?.isVisible=true - return true - } - - func applicationWillTerminate(_ aNotification: Notification) { - UNUserNotificationCenter.current().removeAllDeliveredNotifications() + let menu=NSMenu() + menu.addItem(withTitle: NSLocalizedString("VisibleToEveryone", value: "Visible to everyone", comment: ""), action: nil, keyEquivalent: "") + menu.addItem(withTitle: String(format: NSLocalizedString("DeviceName", value: "Device name: %@", comment: ""), arguments: [Host.current().localizedName!]), action: nil, keyEquivalent: "") + menu.addItem(NSMenuItem.separator()) + + // Add "Recommended Apps" menu item + let recommendedAppsItem = NSMenuItem(title: NSLocalizedString("RecommendedApps", value: "Recommended Apps", comment: ""), action: #selector(openRecommendedApps), keyEquivalent: "") + menu.addItem(recommendedAppsItem) + + // Add "Privacy Policy" menu item + let privacyPolicyItem = NSMenuItem(title: NSLocalizedString("PrivacyPolicy", value: "Privacy Policy", comment: ""), action: #selector(openPrivacyPolicy), keyEquivalent: "") + menu.addItem(privacyPolicyItem) + + menu.addItem(NSMenuItem.separator()) + + let userManualItem = NSMenuItem(title: NSLocalizedString("UserManual", value: "User Manual", comment: ""), action: #selector(openWelcomeScreen), keyEquivalent: "") + menu.addItem(userManualItem) + + menu.addItem(withTitle: NSLocalizedString("Quit", value: "Quit NearDrop", comment: ""), action: #selector(NSApplication.terminate(_:)), keyEquivalent: "") + + + statusItem=NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) + statusItem?.button?.image=NSImage(named: "MenuBarIcon") + statusItem?.menu=menu + statusItem?.behavior = .removalAllowed + + let nc=UNUserNotificationCenter.current() + nc.requestAuthorization(options: [.alert, .sound]) { granted, err in + if !granted{ + DispatchQueue.main.async { + self.showNotificationsDeniedAlert() + } + } + } + nc.delegate=self + let incomingTransfersCategory=UNNotificationCategory(identifier: "INCOMING_TRANSFERS", actions: [ + UNNotificationAction(identifier: "ACCEPT", title: NSLocalizedString("Accept", comment: ""), options: UNNotificationActionOptions.authenticationRequired), + UNNotificationAction(identifier: "DECLINE", title: NSLocalizedString("Decline", comment: "")) + ], intentIdentifiers: []) + let errorsCategory=UNNotificationCategory(identifier: "ERRORS", actions: [], intentIdentifiers: []) + nc.setNotificationCategories([incomingTransfersCategory, errorsCategory]) + NearbyConnectionManager.shared.mainAppDelegate=self + NearbyConnectionManager.shared.becomeVisible() + + openWelcomeScreen() } - + + + @objc func openWelcomeScreen() { + // Create the welcome screen SwiftUI view + let welcomeView = WelcomeScreen() + + // Create an NSWindow to host the SwiftUI view + window = NSWindow( + contentRect: NSRect(x: 0, y: 0, width: 400, height: 300), + styleMask: [.titled, .closable], + backing: .buffered, + defer: false + ) + window?.center() + window?.isReleasedWhenClosed = false + window?.setFrameAutosaveName("WelcomeScreen") + window?.contentView = NSHostingView(rootView: welcomeView) + window?.makeKeyAndOrderFront(nil) + } + + + // Action for "Recommended Apps" menu item + @objc func openRecommendedApps() { + if let url = URL(string: "https://apps.apple.com/de/developer/leon-boettger/id1537384790") { + NSWorkspace.shared.open(url) + } + } + + // Action for "Privacy Policy" menu item + @objc func openPrivacyPolicy() { + if let url = URL(string: " ") { + NSWorkspace.shared.open(url) + } + } + + func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool { + statusItem?.isVisible=true + return true + } + + func applicationWillTerminate(_ aNotification: Notification) { + UNUserNotificationCenter.current().removeAllDeliveredNotifications() + } + func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { return true } - - func showNotificationsDeniedAlert(){ - let alert=NSAlert() - alert.alertStyle = .critical - alert.messageText=NSLocalizedString("NotificationsDenied.Title", value: "Notification Permission Required", comment: "") - alert.informativeText=NSLocalizedString("NotificationsDenied.Message", value: "NearDrop needs to be able to display notifications for incoming file transfers. Please allow notifications in System Settings.", comment: "") - alert.addButton(withTitle: NSLocalizedString("NotificationsDenied.OpenSettings", value: "Open settings", comment: "")) - alert.addButton(withTitle: NSLocalizedString("Quit", value: "Quit NearDrop", comment: "")) - let result=alert.runModal() - if result==NSApplication.ModalResponse.alertFirstButtonReturn{ - NSWorkspace.shared.open(URL(string: "x-apple.systempreferences:com.apple.preference.notifications")!) - }else if result==NSApplication.ModalResponse.alertSecondButtonReturn{ - NSApplication.shared.terminate(nil) - } - } - - func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { - let transferID=response.notification.request.content.userInfo["transferID"]! as! String - NearbyConnectionManager.shared.submitUserConsent(transferID: transferID, accept: response.actionIdentifier=="ACCEPT") - if response.actionIdentifier != "ACCEPT"{ - activeIncomingTransfers.removeValue(forKey: transferID) - } - completionHandler() - } - - func obtainUserConsent(for transfer: TransferMetadata, from device: RemoteDeviceInfo) { - let fileStr:String - if let textTitle=transfer.textDescription{ - fileStr=textTitle - }else if transfer.files.count==1{ - fileStr=transfer.files[0].name - }else{ - fileStr=String.localizedStringWithFormat(NSLocalizedString("NFiles", value: "%d files", comment: ""), transfer.files.count) - } - let notificationContent=UNMutableNotificationContent() - notificationContent.title="NearDrop" - notificationContent.subtitle=String(format:NSLocalizedString("PinCode", value: "PIN: %@", comment: ""), arguments: [transfer.pinCode!]) - notificationContent.body=String(format: NSLocalizedString("DeviceSendingFiles", value: "%1$@ is sending you %2$@", comment: ""), arguments: [device.name, fileStr]) - notificationContent.sound = .default - notificationContent.categoryIdentifier="INCOMING_TRANSFERS" - notificationContent.userInfo=["transferID": transfer.id] - if #available(macOS 11.0, *){ - NDNotificationCenterHackery.removeDefaultAction(notificationContent) - } - let notificationReq=UNNotificationRequest(identifier: "transfer_"+transfer.id, content: notificationContent, trigger: nil) - UNUserNotificationCenter.current().add(notificationReq) - self.activeIncomingTransfers[transfer.id]=TransferInfo(device: device, transfer: transfer) - } - - func incomingTransfer(id: String, didFinishWith error: Error?) { - guard let transfer=self.activeIncomingTransfers[id] else {return} - if let error=error{ - let notificationContent=UNMutableNotificationContent() - notificationContent.title=String(format: NSLocalizedString("TransferError", value: "Failed to receive files from %@", comment: ""), arguments: [transfer.device.name]) - if let ne=(error as? NearbyError){ - switch ne{ - case .inputOutput: - notificationContent.body="I/O Error"; - case .protocolError(_): - notificationContent.body=NSLocalizedString("Error.Protocol", value: "Communication error", comment: "") - case .requiredFieldMissing: - notificationContent.body=NSLocalizedString("Error.Protocol", value: "Communication error", comment: "") - case .ukey2: - notificationContent.body=NSLocalizedString("Error.Crypto", value: "Encryption error", comment: "") - case .canceled(reason: _): - break; // can't happen for incoming transfers - } - }else{ - notificationContent.body=error.localizedDescription - } - notificationContent.categoryIdentifier="ERRORS" - UNUserNotificationCenter.current().add(UNNotificationRequest(identifier: "transferError_"+id, content: notificationContent, trigger: nil)) - } - UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: ["transfer_"+id]) - self.activeIncomingTransfers.removeValue(forKey: id) - } + + func showNotificationsDeniedAlert(){ + let alert=NSAlert() + alert.alertStyle = .critical + alert.messageText=NSLocalizedString("NotificationsDenied.Title", value: "Notification Permission Required", comment: "") + alert.informativeText=NSLocalizedString("NotificationsDenied.Message", value: "NearDrop needs to be able to display notifications for incoming file transfers. Please allow notifications in System Settings.", comment: "") + alert.addButton(withTitle: NSLocalizedString("NotificationsDenied.OpenSettings", value: "Open settings", comment: "")) + alert.addButton(withTitle: NSLocalizedString("Quit", value: "Quit NearDrop", comment: "")) + let result=alert.runModal() + if result==NSApplication.ModalResponse.alertFirstButtonReturn{ + NSWorkspace.shared.open(URL(string: "x-apple.systempreferences:com.apple.preference.notifications")!) + }else if result==NSApplication.ModalResponse.alertSecondButtonReturn{ + NSApplication.shared.terminate(nil) + } + } + + func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { + let transferID=response.notification.request.content.userInfo["transferID"]! as! String + NearbyConnectionManager.shared.submitUserConsent(transferID: transferID, accept: response.actionIdentifier=="ACCEPT") + if response.actionIdentifier != "ACCEPT"{ + activeIncomingTransfers.removeValue(forKey: transferID) + } + completionHandler() + } + + func obtainUserConsent(for transfer: TransferMetadata, from device: RemoteDeviceInfo) { + let fileStr:String + if let textTitle=transfer.textDescription{ + fileStr=textTitle + }else if transfer.files.count==1{ + fileStr=transfer.files[0].name + }else{ + fileStr=String.localizedStringWithFormat(NSLocalizedString("NFiles", value: "%d files", comment: ""), transfer.files.count) + } + let notificationContent=UNMutableNotificationContent() + notificationContent.title="NearDrop" + notificationContent.subtitle=String(format:NSLocalizedString("PinCode", value: "PIN: %@", comment: ""), arguments: [transfer.pinCode!]) + notificationContent.body=String(format: NSLocalizedString("DeviceSendingFiles", value: "%1$@ is sending you %2$@", comment: ""), arguments: [device.name, fileStr]) + notificationContent.sound = .default + notificationContent.categoryIdentifier="INCOMING_TRANSFERS" + notificationContent.userInfo=["transferID": transfer.id] + if #available(macOS 11.0, *){ + NDNotificationCenterHackery.removeDefaultAction(notificationContent) + } + let notificationReq=UNNotificationRequest(identifier: "transfer_"+transfer.id, content: notificationContent, trigger: nil) + UNUserNotificationCenter.current().add(notificationReq) + self.activeIncomingTransfers[transfer.id]=TransferInfo(device: device, transfer: transfer) + } + + func incomingTransfer(id: String, didFinishWith error: Error?) { + guard let transfer=self.activeIncomingTransfers[id] else {return} + if let error=error{ + let notificationContent=UNMutableNotificationContent() + notificationContent.title=String(format: NSLocalizedString("TransferError", value: "Failed to receive files from %@", comment: ""), arguments: [transfer.device.name]) + if let ne=(error as? NearbyError){ + switch ne{ + case .inputOutput: + notificationContent.body="I/O Error"; + case .protocolError(_): + notificationContent.body=NSLocalizedString("Error.Protocol", value: "Communication error", comment: "") + case .requiredFieldMissing: + notificationContent.body=NSLocalizedString("Error.Protocol", value: "Communication error", comment: "") + case .ukey2: + notificationContent.body=NSLocalizedString("Error.Crypto", value: "Encryption error", comment: "") + case .canceled(reason: _): + break; // can't happen for incoming transfers + } + }else{ + notificationContent.body=error.localizedDescription + } + notificationContent.categoryIdentifier="ERRORS" + UNUserNotificationCenter.current().add(UNNotificationRequest(identifier: "transferError_"+id, content: notificationContent, trigger: nil)) + } + UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: ["transfer_"+id]) + self.activeIncomingTransfers.removeValue(forKey: id) + } } struct TransferInfo{ - let device:RemoteDeviceInfo - let transfer:TransferMetadata + let device:RemoteDeviceInfo + let transfer:TransferMetadata } diff --git a/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-1024.png b/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-1024.png new file mode 100644 index 0000000..8898c3f Binary files /dev/null and b/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-1024.png differ diff --git a/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-128.png b/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-128.png new file mode 100644 index 0000000..36ad3ea Binary files /dev/null and b/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-128.png differ diff --git a/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-16.png b/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-16.png new file mode 100644 index 0000000..e0489f1 Binary files /dev/null and b/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-16.png differ diff --git a/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-256.png b/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-256.png new file mode 100644 index 0000000..19b1a5a Binary files /dev/null and b/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-256.png differ diff --git a/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-32.png b/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-32.png new file mode 100644 index 0000000..0ba955e Binary files /dev/null and b/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-32.png differ diff --git a/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-512.png b/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-512.png new file mode 100644 index 0000000..9d2b605 Binary files /dev/null and b/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-512.png differ diff --git a/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-64.png b/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-64.png new file mode 100644 index 0000000..a6168f6 Binary files /dev/null and b/NearDrop/Assets.xcassets/AppIcon.appiconset/1024-64.png differ diff --git a/NearDrop/Assets.xcassets/AppIcon.appiconset/1024.png b/NearDrop/Assets.xcassets/AppIcon.appiconset/1024.png deleted file mode 100644 index 54f8023..0000000 Binary files a/NearDrop/Assets.xcassets/AppIcon.appiconset/1024.png and /dev/null differ diff --git a/NearDrop/Assets.xcassets/AppIcon.appiconset/128.png b/NearDrop/Assets.xcassets/AppIcon.appiconset/128.png deleted file mode 100644 index d215841..0000000 Binary files a/NearDrop/Assets.xcassets/AppIcon.appiconset/128.png and /dev/null differ diff --git a/NearDrop/Assets.xcassets/AppIcon.appiconset/16.png b/NearDrop/Assets.xcassets/AppIcon.appiconset/16.png deleted file mode 100644 index b4a8027..0000000 Binary files a/NearDrop/Assets.xcassets/AppIcon.appiconset/16.png and /dev/null differ diff --git a/NearDrop/Assets.xcassets/AppIcon.appiconset/256 1.png b/NearDrop/Assets.xcassets/AppIcon.appiconset/256 1.png deleted file mode 100644 index 1d1bcc1..0000000 Binary files a/NearDrop/Assets.xcassets/AppIcon.appiconset/256 1.png and /dev/null differ diff --git a/NearDrop/Assets.xcassets/AppIcon.appiconset/256.png b/NearDrop/Assets.xcassets/AppIcon.appiconset/256.png deleted file mode 100644 index 1d1bcc1..0000000 Binary files a/NearDrop/Assets.xcassets/AppIcon.appiconset/256.png and /dev/null differ diff --git a/NearDrop/Assets.xcassets/AppIcon.appiconset/32 1.png b/NearDrop/Assets.xcassets/AppIcon.appiconset/32 1.png deleted file mode 100644 index 21f8b8f..0000000 Binary files a/NearDrop/Assets.xcassets/AppIcon.appiconset/32 1.png and /dev/null differ diff --git a/NearDrop/Assets.xcassets/AppIcon.appiconset/32.png b/NearDrop/Assets.xcassets/AppIcon.appiconset/32.png deleted file mode 100644 index 21f8b8f..0000000 Binary files a/NearDrop/Assets.xcassets/AppIcon.appiconset/32.png and /dev/null differ diff --git a/NearDrop/Assets.xcassets/AppIcon.appiconset/512 1.png b/NearDrop/Assets.xcassets/AppIcon.appiconset/512 1.png deleted file mode 100644 index 858de45..0000000 Binary files a/NearDrop/Assets.xcassets/AppIcon.appiconset/512 1.png and /dev/null differ diff --git a/NearDrop/Assets.xcassets/AppIcon.appiconset/512.png b/NearDrop/Assets.xcassets/AppIcon.appiconset/512.png deleted file mode 100644 index 858de45..0000000 Binary files a/NearDrop/Assets.xcassets/AppIcon.appiconset/512.png and /dev/null differ diff --git a/NearDrop/Assets.xcassets/AppIcon.appiconset/64.png b/NearDrop/Assets.xcassets/AppIcon.appiconset/64.png deleted file mode 100644 index 7b29321..0000000 Binary files a/NearDrop/Assets.xcassets/AppIcon.appiconset/64.png and /dev/null differ diff --git a/NearDrop/Assets.xcassets/AppIcon.appiconset/Contents.json b/NearDrop/Assets.xcassets/AppIcon.appiconset/Contents.json index f6b252f..68ff1f9 100644 --- a/NearDrop/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/NearDrop/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,61 +1,61 @@ { "images" : [ { - "filename" : "16.png", + "filename" : "1024-16.png", "idiom" : "mac", "scale" : "1x", "size" : "16x16" }, { - "filename" : "32.png", + "filename" : "1024-32.png", "idiom" : "mac", "scale" : "2x", "size" : "16x16" }, { - "filename" : "32 1.png", + "filename" : "1024-32.png", "idiom" : "mac", "scale" : "1x", "size" : "32x32" }, { - "filename" : "64.png", + "filename" : "1024-64.png", "idiom" : "mac", "scale" : "2x", "size" : "32x32" }, { - "filename" : "128.png", + "filename" : "1024-128.png", "idiom" : "mac", "scale" : "1x", "size" : "128x128" }, { - "filename" : "256.png", + "filename" : "1024-256.png", "idiom" : "mac", "scale" : "2x", "size" : "128x128" }, { - "filename" : "256 1.png", + "filename" : "1024-256.png", "idiom" : "mac", "scale" : "1x", "size" : "256x256" }, { - "filename" : "512.png", + "filename" : "1024-512.png", "idiom" : "mac", "scale" : "2x", "size" : "256x256" }, { - "filename" : "512 1.png", + "filename" : "1024-512.png", "idiom" : "mac", "scale" : "1x", "size" : "512x512" }, { - "filename" : "1024.png", + "filename" : "1024-1024.png", "idiom" : "mac", "scale" : "2x", "size" : "512x512" diff --git a/NearDrop/Assets.xcassets/AppIconHighRes.imageset/1024.png b/NearDrop/Assets.xcassets/AppIconHighRes.imageset/1024.png new file mode 100644 index 0000000..e9106e7 Binary files /dev/null and b/NearDrop/Assets.xcassets/AppIconHighRes.imageset/1024.png differ diff --git a/NearDrop/Assets.xcassets/AppIconHighRes.imageset/Contents.json b/NearDrop/Assets.xcassets/AppIconHighRes.imageset/Contents.json new file mode 100644 index 0000000..94202f5 --- /dev/null +++ b/NearDrop/Assets.xcassets/AppIconHighRes.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "1024.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/NearDrop/Base.lproj/Localizable.strings b/NearDrop/Base.lproj/Localizable.strings index 6d28946..acc0b11 100644 --- a/NearDrop/Base.lproj/Localizable.strings +++ b/NearDrop/Base.lproj/Localizable.strings @@ -1,4 +1,4 @@ -/* No comment provided by engineer. */ +/* No comment provided by engineer. */ "Accept" = "Accept"; /* No comment provided by engineer. */ @@ -40,3 +40,14 @@ /* No comment provided by engineer. */ "VisibleToEveryone" = "Visible to everyone"; +"WelcomeToNearDrop" = "Welcome to NearDrop"; + +"Acknowledgements" = "Acknowledgements"; + +"UserManualDescription" = "When NearDrop is running, it will appear in the menu bar at the top of your screen. Click the NearDrop icon if you would like to stop receiving files. + +To send files from your Android device to your Mac, just select \"Share\" or tap the Share Icon for a file you want to transfer, and select \"Quick Share\". Your Mac will be listed as an available device. + +After that, you will see a notification on your Mac. Hover over the notification to accept or decline the file transfer. + +Important: Your Android device and your Mac need to be on the same network to transfer files. If you are promted to allow incoming connections, please allow them."; diff --git a/NearDrop/Info.plist b/NearDrop/Info.plist new file mode 100644 index 0000000..bc11256 --- /dev/null +++ b/NearDrop/Info.plist @@ -0,0 +1,8 @@ + + + + + ITSAppUsesNonExemptEncryption + + + diff --git a/NearDrop/MainMenu.xib b/NearDrop/MainMenu.xib index 1c336d0..51272b4 100644 --- a/NearDrop/MainMenu.xib +++ b/NearDrop/MainMenu.xib @@ -1,8 +1,8 @@ - + - + diff --git a/NearDrop/WelcomeScreen.swift b/NearDrop/WelcomeScreen.swift new file mode 100644 index 0000000..295ecc2 --- /dev/null +++ b/NearDrop/WelcomeScreen.swift @@ -0,0 +1,203 @@ +// +// WelcomeScreen.swift +// NearDrop +// +// Created by Leon Böttger on 03.01.25. +// + +import SwiftUI + +struct WelcomeScreen: View { + + @State private var newWindow: NSWindow? // Retain the NSWindow object + + var body: some View { + + ScrollView { + + VStack { + Image("AppIconHighRes") + .resizable() + .frame(width: 150, height: 150) + .padding(.top, 50) + + Text("WelcomeToNearDrop") + .font(.largeTitle) + .padding() + + Text("UserManualDescription") + .multilineTextAlignment(.center) + .padding() + + + Button { + openNewWindow() + } label: { + Text("Acknowledgements") + .underline() + .font(.footnote) + .opacity(0.5) + } + .buttonStyle(.plain) + .padding() + + + } + .frame(maxWidth: 500) + .frame(maxWidth: .infinity) + } + + .frame(width: 1000, height: 600) + } + + func openNewWindow() { + // Create a new NSWindow and retain it in the `newWindow` property + let window = NSWindow( + contentRect: NSRect(x: 0, y: 0, width: 500, height: 400), + styleMask: [.titled, .closable, .resizable], + backing: .buffered, + defer: false + ) + window.center() + window.isReleasedWhenClosed = false + window.title = NSLocalizedString("Acknowledgements", value: "Acknowledgements", comment: "") + window.contentView = NSHostingView(rootView: LicensePage()) + window.makeKeyAndOrderFront(nil) + + // Retain the window to prevent deallocation + newWindow = window + } +} + + +struct LicensePage: View { + var body: some View { + ScrollView { + Text(""" +NearDrop +https://github.com/grishka/NearDrop + +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to + + +ASN1 +https://github.com/leif-ibsen/ASN1 +Copyright (c) 2021 Leif Ibsen +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +BigInt +https://github.com/leif-ibsen/BigInt +Copyright (c) 2021 Leif Ibsen +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +SwiftECC +https://github.com/leif-ibsen/SwiftECC +Copyright (c) 2021 Leif Ibsen +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +swift-protobuf +https://github.com/apple/swift-protobuf +Copyright 2024 Apple Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +""") + .padding() + } + } +} + + +#Preview { + WelcomeScreen() +} diff --git a/NearDrop/de.lproj/Localizable.strings b/NearDrop/de.lproj/Localizable.strings index 415296f..c895f9c 100644 --- a/NearDrop/de.lproj/Localizable.strings +++ b/NearDrop/de.lproj/Localizable.strings @@ -1,4 +1,4 @@ -/* No comment provided by engineer. */ +/* No comment provided by engineer. */ "Accept" = "Akzeptieren"; /* No comment provided by engineer. */ @@ -40,3 +40,14 @@ /* No comment provided by engineer. */ "VisibleToEveryone" = "Für alle sichtbar"; +"WelcomeToNearDrop" = "Willkommen bei NearDrop"; + +"Acknowledgements" = "Danksagungen"; + +"UserManualDescription" = "Wenn NearDrop ausgeführt wird, erscheint es in der Menüleiste am oberen Rand Ihres Bildschirms. Klicken Sie auf das NearDrop-Symbol, wenn Sie den Empfang von Dateien beenden möchten. + +Um Dateien von Ihrem Android-Gerät an Ihren Mac zu senden, wählen Sie einfach „Teilen“ oder tippen Sie auf das Freigabesymbol für eine Datei, die Sie übertragen möchten, und wählen Sie „Quick Share“. Ihr Mac wird als verfügbares Gerät aufgelistet. + +Daraufhin wird eine Benachrichtigung auf Ihrem Mac angezeigt. Bewegen Sie den Mauszeiger über die Benachrichtigung, um die Dateiübertragung zu akzeptieren oder abzulehnen. + +Wichtig: Ihr Android-Gerät und Ihr Mac müssen sich im selben Netzwerk befinden, um Dateien zu übertragen. Wenn Sie aufgefordert werden, eingehende Verbindungen zuzulassen, lassen Sie sie bitte zu"; diff --git a/ShareExtension/Assets.xcassets/NearDropIcon.imageset/1024.png b/ShareExtension/Assets.xcassets/NearDropIcon.imageset/1024.png new file mode 100644 index 0000000..e9106e7 Binary files /dev/null and b/ShareExtension/Assets.xcassets/NearDropIcon.imageset/1024.png differ diff --git a/ShareExtension/Assets.xcassets/NearDropIcon.imageset/16.png b/ShareExtension/Assets.xcassets/NearDropIcon.imageset/16.png deleted file mode 100644 index b4a8027..0000000 Binary files a/ShareExtension/Assets.xcassets/NearDropIcon.imageset/16.png and /dev/null differ diff --git a/ShareExtension/Assets.xcassets/NearDropIcon.imageset/32.png b/ShareExtension/Assets.xcassets/NearDropIcon.imageset/32.png deleted file mode 100644 index 21f8b8f..0000000 Binary files a/ShareExtension/Assets.xcassets/NearDropIcon.imageset/32.png and /dev/null differ diff --git a/ShareExtension/Assets.xcassets/NearDropIcon.imageset/Contents.json b/ShareExtension/Assets.xcassets/NearDropIcon.imageset/Contents.json index 7dbabe1..94202f5 100644 --- a/ShareExtension/Assets.xcassets/NearDropIcon.imageset/Contents.json +++ b/ShareExtension/Assets.xcassets/NearDropIcon.imageset/Contents.json @@ -1,12 +1,11 @@ { "images" : [ { - "filename" : "16.png", + "filename" : "1024.png", "idiom" : "universal", "scale" : "1x" }, { - "filename" : "32.png", "idiom" : "universal", "scale" : "2x" }, diff --git a/ShareExtension/Base.lproj/Localizable.strings b/ShareExtension/Base.lproj/Localizable.strings index 1dd36a7..538030e 100644 Binary files a/ShareExtension/Base.lproj/Localizable.strings and b/ShareExtension/Base.lproj/Localizable.strings differ diff --git a/ShareExtension/ar.lproj/Localizable.strings b/ShareExtension/ar.lproj/Localizable.strings index 1c90e46..aa27671 100644 --- a/ShareExtension/ar.lproj/Localizable.strings +++ b/ShareExtension/ar.lproj/Localizable.strings @@ -27,3 +27,7 @@ /* No comment provided by engineer. */ "UnsupportedType" = "نوع المرفق غير مدعوم"; + +"RecommendedApps" = "التطبيقات الموصى بها"; +"PrivacyPolicy" = "سياسة الخصوصية"; +"UserManual" = "دليل المستخدم"; diff --git a/ShareExtension/ja.lproj/Localizable.strings b/ShareExtension/ja.lproj/Localizable.strings index 2798477..e557c49 100644 Binary files a/ShareExtension/ja.lproj/Localizable.strings and b/ShareExtension/ja.lproj/Localizable.strings differ diff --git a/ShareExtension/ko.lproj/Localizable.strings b/ShareExtension/ko.lproj/Localizable.strings index 553aa9d..5bafdcb 100644 Binary files a/ShareExtension/ko.lproj/Localizable.strings and b/ShareExtension/ko.lproj/Localizable.strings differ diff --git a/ShareExtension/nl.lproj/Localizable.strings b/ShareExtension/nl.lproj/Localizable.strings index 54e2ec7..3def75b 100644 Binary files a/ShareExtension/nl.lproj/Localizable.strings and b/ShareExtension/nl.lproj/Localizable.strings differ diff --git a/ShareExtension/pt-PT.lproj/Localizable.strings b/ShareExtension/pt-PT.lproj/Localizable.strings index 0663d4f..b9d1d51 100644 Binary files a/ShareExtension/pt-PT.lproj/Localizable.strings and b/ShareExtension/pt-PT.lproj/Localizable.strings differ diff --git a/ShareExtension/ro.lproj/Localizable.strings b/ShareExtension/ro.lproj/Localizable.strings index 4ec0877..829516e 100644 Binary files a/ShareExtension/ro.lproj/Localizable.strings and b/ShareExtension/ro.lproj/Localizable.strings differ diff --git a/ShareExtension/ru.lproj/Localizable.strings b/ShareExtension/ru.lproj/Localizable.strings index 9f22da1..fcd559b 100644 Binary files a/ShareExtension/ru.lproj/Localizable.strings and b/ShareExtension/ru.lproj/Localizable.strings differ diff --git a/ShareExtension/uk.lproj/Localizable.strings b/ShareExtension/uk.lproj/Localizable.strings index a04c24a..8d536c7 100644 Binary files a/ShareExtension/uk.lproj/Localizable.strings and b/ShareExtension/uk.lproj/Localizable.strings differ diff --git a/ShareExtension/zh-Hans.lproj/Localizable.strings b/ShareExtension/zh-Hans.lproj/Localizable.strings index b81bd1e..b423294 100644 --- a/ShareExtension/zh-Hans.lproj/Localizable.strings +++ b/ShareExtension/zh-Hans.lproj/Localizable.strings @@ -28,3 +28,6 @@ /* No comment provided by engineer. */ "UnsupportedType" = "不支持的文件类型"; +"RecommendedApps" = "推荐应用"; +"PrivacyPolicy" = "隐私政策"; +"UserManual" = "用户手册";