Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: send push notifications on VPN failures#196

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
ethanndickson wants to merge1 commit intomainfromethan/push-notif-vpn-failure
Closed
Show file tree
Hide file tree
Changes fromall 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
14 changes: 9 additions & 5 deletionsCoder-Desktop/Coder-Desktop/Coder_DesktopApp.swift
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -42,17 +42,16 @@ struct DesktopApp: App {
@MainActor
class AppDelegate: NSObject, NSApplicationDelegate {
private var logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "app-delegate")
privatevar menuBar: MenuBarController?
var menuBar: MenuBarController?
let vpn: CoderVPNService
let state: AppState
let fileSyncDaemon: MutagenDaemon
let urlHandler: URLHandler
let notifDelegate: NotifDelegate
let helper: HelperService
let autoUpdater: UpdaterService

override init() {
notifDelegate = NotifDelegate()
AppDelegate.registerNotificationCategories()
vpn = CoderVPNService()
helper = HelperService()
autoUpdater = UpdaterService()
Expand All@@ -79,8 +78,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
}
self.fileSyncDaemon = fileSyncDaemon
urlHandler = URLHandler(state: state, vpn: vpn)
super.init()
// `delegate` is weak
UNUserNotificationCenter.current().delegate =notifDelegate
UNUserNotificationCenter.current().delegate =self
}

func applicationDidFinishLaunching(_: Notification) {
Expand DownExpand Up@@ -161,7 +161,11 @@ class AppDelegate: NSObject, NSApplicationDelegate {
do { try urlHandler.handle(url) } catch let handleError {
Task {
do {
try await sendNotification(title: "Failed to handle link", body: handleError.description)
try await sendNotification(
title: "Failed to handle link",
body: handleError.description,
category: .uriFailure
)
} catch let notifError {
logger.error("Failed to send notification (\(handleError.description)): \(notifError)")
}
Expand Down
48 changes: 44 additions & 4 deletionsCoder-Desktop/Coder-Desktop/Notifications.swift
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
import UserNotifications

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The oldNotifDelegate class was removed but I don’t see its full definition cleaned up. Please remove any leftoverNotifDelegate declaration to avoid dead code.

Copilot uses AI. Check for mistakes.


class NotifDelegate: NSObject, UNUserNotificationCenterDelegate {
override init() {
super.init()
extension AppDelegate: UNUserNotificationCenterDelegate {
static func registerNotificationCategories() {
let vpnFailure = UNNotificationCategory(
identifier: NotificationCategory.vpnFailure.rawValue,
actions: [],
intentIdentifiers: [],
options: []
)

let uriFailure = UNNotificationCategory(
identifier: NotificationCategory.uriFailure.rawValue,
actions: [],
intentIdentifiers: [],
options: []
)

UNUserNotificationCenter.current()
.setNotificationCategories([vpnFailure, uriFailure])
}

// This function is required for notifications to appear as banners whilst the app is running.
Expand All@@ -13,9 +28,28 @@ class NotifDelegate: NSObject, UNUserNotificationCenterDelegate {
) async -> UNNotificationPresentationOptions {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Ensure theuserNotificationCenter(_:willPresent:withCompletionHandler:) method is inside theAppDelegate extension so banners still appear while the app is active.

Copilot uses AI. Check for mistakes.

[.banner]
}

nonisolated func userNotificationCenter(
_: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void
) {
let category = response.notification.request.content.categoryIdentifier
let action = response.actionIdentifier
switch (category, action) {
// Default action for VPN failure notification
case (NotificationCategory.vpnFailure.rawValue, UNNotificationDefaultActionIdentifier):
Task { @MainActor in
self.menuBar?.menuBarExtra.toggleVisibility()
}
default:
break
}
completionHandler()
}
}

func sendNotification(title: String, body: String) async throws {
func sendNotification(title: String, body: String, category: NotificationCategory) async throws {
let nc = UNUserNotificationCenter.current()
let granted = try await nc.requestAuthorization(options: [.alert, .badge])
guard granted else {
Expand All@@ -24,5 +58,11 @@ func sendNotification(title: String, body: String) async throws {
let content = UNMutableNotificationContent()
content.title = title
content.body = body
content.categoryIdentifier = category.rawValue
try await nc.add(.init(identifier: UUID().uuidString, content: content, trigger: nil))
}

enum NotificationCategory: String {
case vpnFailure = "VPN_FAILURE"
case uriFailure = "URI_FAILURE"
}
12 changes: 12 additions & 0 deletionsCoder-Desktop/Coder-Desktop/VPN/VPNService.swift
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -61,6 +61,18 @@ final class CoderVPNService: NSObject, VPNService {
if tunnelState == .connecting {
progress = .init(stage: .initial, downloadProgress: nil)
}
if case let .failed(tunnelError) = tunnelState, tunnelState != oldValue {
Task {
do {
try await sendNotification(
title: "Coder Connect has failed!",
body: tunnelError.description, category: .vpnFailure
)
} catch let notifError {
logger.error("Failed to send notification (\(tunnelError.description)): \(notifError)")
}
}
}
}
}

Expand Down
2 changes: 1 addition & 1 deletionCoder-Desktop/project.yml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -98,7 +98,7 @@ packages:
# - Set onAppear/disappear handlers.
# The upstream repo has a purposefully limited API
url: https://github.com/coder/fluid-menu-bar-extra
revision:8e1d8b8
revision:afc9256
KeychainAccess:
url: https://github.com/kishikawakatsumi/KeychainAccess
branch: e0c7eebc5a4465a3c4680764f26b7a61f567cdaf
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp