Skip to content

Commit 83b1554

Browse files
committed
feat: send push notifications for invalid coder scheme URIs
1 parent 5ece015 commit 83b1554

File tree

3 files changed

+44
-3
lines changed

3 files changed

+44
-3
lines changed

Coder-Desktop/Coder-Desktop/Coder_DesktopApp.swift

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import FluidMenuBarExtra
22
import NetworkExtension
3+
import os
34
import SDWebImageSVGCoder
45
import SDWebImageSwiftUI
56
import SwiftUI
7+
import UserNotifications
68
import VPNLib
79

810
@main
@@ -36,13 +38,16 @@ struct DesktopApp: App {
3638

3739
@MainActor
3840
class AppDelegate: NSObject, NSApplicationDelegate {
41+
private var logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "app-delegate")
3942
private var menuBar: MenuBarController?
4043
let vpn: CoderVPNService
4144
let state: AppState
4245
let fileSyncDaemon: MutagenDaemon
4346
let urlHandler: URLHandler
47+
let notifDelegate: NotifDelegate
4448

4549
override init() {
50+
notifDelegate = NotifDelegate()
4651
vpn = CoderVPNService()
4752
let state = AppState(onChange: vpn.configureTunnelProviderProtocol)
4853
vpn.onStart = {
@@ -67,6 +72,8 @@ class AppDelegate: NSObject, NSApplicationDelegate {
6772
}
6873
self.fileSyncDaemon = fileSyncDaemon
6974
urlHandler = URLHandler(state: state, vpn: vpn)
75+
// `delegate` is weak
76+
UNUserNotificationCenter.current().delegate = notifDelegate
7077
}
7178

7279
func applicationDidFinishLaunching(_: Notification) {
@@ -135,9 +142,14 @@ class AppDelegate: NSObject, NSApplicationDelegate {
135142
// We only accept one at time, for now
136143
return
137144
}
138-
do { try urlHandler.handle(url) } catch {
139-
// TODO: Push notification
140-
print(error.description)
145+
do { try urlHandler.handle(url) } catch let handleError {
146+
Task {
147+
do {
148+
try await sendNotification(title: "Failed to open link", body: handleError.description)
149+
} catch let notifError {
150+
logger.error("Failed to send notification (\(handleError.description)): \(notifError)")
151+
}
152+
}
141153
}
142154
}
143155
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import UserNotifications
2+
3+
class NotifDelegate: NSObject, UNUserNotificationCenterDelegate {
4+
override init() {
5+
super.init()
6+
}
7+
8+
// This function is required for notifications to appear as banners whilst the app is running.
9+
// We're effectively forwarding the notification back to the OS
10+
nonisolated func userNotificationCenter(
11+
_: UNUserNotificationCenter,
12+
willPresent _: UNNotification
13+
) async -> UNNotificationPresentationOptions {
14+
[.banner]
15+
}
16+
}
17+
18+
func sendNotification(title: String, body: String) async throws {
19+
let nc = UNUserNotificationCenter.current()
20+
let granted = try await nc.requestAuthorization(options: [.alert, .badge])
21+
guard granted else {
22+
return
23+
}
24+
let content = UNMutableNotificationContent()
25+
content.title = title
26+
content.body = body
27+
try await nc.add(.init(identifier: UUID().uuidString, content: content, trigger: nil))
28+
}

Coder-Desktop/project.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ targets:
147147
com.apple.developer.system-extension.install: true
148148
com.apple.security.application-groups:
149149
- $(TeamIdentifierPrefix)com.coder.Coder-Desktop
150+
aps-environment: development
150151
settings:
151152
base:
152153
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon # Sets the app icon to "AppIcon".

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy