Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions NetBird.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
objects = {

/* Begin PBXBuildFile section */
FD0000000000000000000002 /* FileDropModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD0000000000000000000001 /* FileDropModels.swift */; };
FD0000000000000000000003 /* FileDropModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD0000000000000000000001 /* FileDropModels.swift */; };
FD0000000000000000000004 /* FileDropModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD0000000000000000000001 /* FileDropModels.swift */; };
FD0000000000000000000005 /* FileDropModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD0000000000000000000001 /* FileDropModels.swift */; };
FD0000000000000000000007 /* FilesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD0000000000000000000006 /* FilesViewModel.swift */; };
FD0000000000000000000009 /* iOSFilesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD0000000000000000000008 /* iOSFilesView.swift */; };
FD0000000000000000000011 /* FileSendView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD0000000000000000000010 /* FileSendView.swift */; };
0C71C019350D42AB8F110336 /* iOSSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F8A4B98A775451786C5DDF8 /* iOSSettingsView.swift */; };
1C4E6A81CD33FF6D2DEFF8D5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 91FA1F06D3375864C74EAB3B /* Foundation.framework */; };
AA000C012F22000C00000001 /* NetBirdSDK.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50D402932BD9143900D4AC5B /* NetBirdSDK.xcframework */; };
Expand Down Expand Up @@ -290,6 +297,10 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
FD0000000000000000000001 /* FileDropModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileDropModels.swift; sourceTree = "<group>"; };
FD0000000000000000000006 /* FilesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilesViewModel.swift; sourceTree = "<group>"; };
FD0000000000000000000008 /* iOSFilesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSFilesView.swift; sourceTree = "<group>"; };
FD0000000000000000000010 /* FileSendView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileSendView.swift; sourceTree = "<group>"; };
2F8A4B98A775451786C5DDF8 /* iOSSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSSettingsView.swift; sourceTree = "<group>"; };
3E054D83063E440DAD0C52FA /* GlobalConstantsTests.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = GlobalConstantsTests.swift; sourceTree = "<group>"; };
42873052F9544A89B1408339 /* iOSPeersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSPeersView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -626,6 +637,7 @@
50C727EA2A82479B006E898D /* NetbirdKit */ = {
isa = PBXGroup;
children = (
FD0000000000000000000001 /* FileDropModels.swift */,
978FC46F2EEDF167002D0EB8 /* AppLogger.swift */,
A7C0DE002F9A0001001A2B3C /* GoCrashCapture.swift */,
F1B292092EE0BC40001D91B8 /* GlobalConstants.swift */,
Expand Down Expand Up @@ -667,6 +679,7 @@
50E608012A7950C000BAF09B /* ViewModels */ = {
isa = PBXGroup;
children = (
FD0000000000000000000006 /* FilesViewModel.swift */,
F1258DE12ED4EE4900C0D205 /* ServerViewModel.swift */,
50E608122A7958B100BAF09B /* MainViewModel.swift */,
50D402962BD9B89300D4AC5B /* PeerViewModel.swift */,
Expand Down Expand Up @@ -740,6 +753,8 @@
A35A69207D60447AA6465276 /* iOS */ = {
isa = PBXGroup;
children = (
FD0000000000000000000010 /* FileSendView.swift */,
FD0000000000000000000008 /* iOSFilesView.swift */,
8DE6A20955914E68BFADDEED /* iOSConnectionView.swift */,
42873052F9544A89B1408339 /* iOSPeersView.swift */,
C7A1CFF65CC44187912007EC /* iOSNetworksView.swift */,
Expand Down Expand Up @@ -1083,6 +1098,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
FD0000000000000000000004 /* FileDropModels.swift in Sources */,
445B5F752EECAF01008932B8 /* GlobalConstants.swift in Sources */,
A1C3D5E92F000003001A2B3C /* WiFiOnDemandPolicy.swift in Sources */,
A1C3D5ED2F000007001A2B3C /* CellularOnDemandPolicy.swift in Sources */,
Expand Down Expand Up @@ -1124,6 +1140,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
FD0000000000000000000005 /* FileDropModels.swift in Sources */,
44F3E3982EE2F89200C87FEC /* NetworkChangeListener.swift in Sources */,
44F3E38B2EE214D300C87FEC /* PacketTunnelProviderSettingsManager.swift in Sources */,
445B5F742EECAE4E008932B8 /* EnvVarPackager.swift in Sources */,
Expand Down Expand Up @@ -1152,6 +1169,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
FD0000000000000000000003 /* FileDropModels.swift in Sources */,
50CD81632AD0595E00CF830B /* DNSManager.swift in Sources */,
50C5D3102BDD96CF003159BE /* RoutesSelectionDetails.swift in Sources */,
50C727ED2A824C10006E898D /* NetBirdAdapter.swift in Sources */,
Expand Down Expand Up @@ -1181,6 +1199,10 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
FD0000000000000000000011 /* FileSendView.swift in Sources */,
FD0000000000000000000009 /* iOSFilesView.swift in Sources */,
FD0000000000000000000007 /* FilesViewModel.swift in Sources */,
FD0000000000000000000002 /* FileDropModels.swift in Sources */,
50CD84362AD82F9400CF830B /* ServerView.swift in Sources */,
50C5D30F2BDD96CF003159BE /* RoutesSelectionDetails.swift in Sources */,
50A8911D2A792A15007C48FC /* MainView.swift in Sources */,
Expand Down
4 changes: 4 additions & 0 deletions NetBird/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
<string>inter-variable.ttf</string>
<string>jetbrains-mono-variable.ttf</string>
</array>
<key>UIFileSharingEnabled</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>CFBundleURLTypes</key>
<array>
<dict>
Expand Down
46 changes: 46 additions & 0 deletions NetBird/Source/App/NetBirdApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDele

let center = UNUserNotificationCenter.current()
center.delegate = self
center.setNotificationCategories([AppDelegate.fileDropOfferCategory()])
center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
if let error = error {
AppLogger.shared.log("Notification authorization error: \(error.localizedDescription)")
Expand Down Expand Up @@ -108,8 +109,49 @@ class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDele
if response.notification.request.identifier == GlobalConstants.notificationLoginRequired {
NotificationCenter.default.post(name: .netbirdLoginNotificationTapped, object: nil)
}
handleFileDropResponse(response)
completionHandler()
}

/// Accept and Decline on an incoming offer, so answering does not require
/// opening the app first. The category lives here rather than in the
/// extension: categories registered from a Network Extension are not
/// reliably picked up by the system.
private static func fileDropOfferCategory() -> UNNotificationCategory {
let accept = UNNotificationAction(
identifier: FileDropNotification.acceptAction,
title: NSLocalizedString("file_drop_accept", value: "Accept", comment: ""),
options: [])
let decline = UNNotificationAction(
identifier: FileDropNotification.declineAction,
title: NSLocalizedString("file_drop_decline", value: "Decline", comment: ""),
options: [.destructive])

return UNNotificationCategory(
identifier: FileDropNotification.offerCategory,
actions: [accept, decline],
intentIdentifiers: [],
options: [])
}

private func handleFileDropResponse(_ response: UNNotificationResponse) {
let verb: String
switch response.actionIdentifier {
case FileDropNotification.acceptAction:
verb = "Accept"
case FileDropNotification.declineAction:
verb = "Decline"
default:
return
}

guard let id = response.notification.request.content
.userInfo[FileDropNotification.transferIDKey] as? String, !id.isEmpty else { return }

DispatchQueue.main.async {
FilesViewModel.shared.answerFromNotification(verb: verb, id: id)
}
}
}
#endif

Expand Down Expand Up @@ -144,6 +186,10 @@ struct NetBirdApp: App {
handleWidgetURL(url, viewModel: viewModel)
}
.onAppear {
// Bound as early as the view model exists, so an answer
// queued by a notification action is released before the
// Files tab is ever opened.
FilesViewModel.shared.bind(adapter: viewModel.networkExtensionAdapter)
if let url = pendingURL {
handleWidgetURL(url, viewModel: viewModel)
pendingURL = nil
Expand Down
Loading
Loading