about summary refs log tree commit diff
path: root/modules/BlueskyNSE
diff options
context:
space:
mode:
authorHailey <me@haileyok.com>2024-05-15 11:49:07 -0700
committerGitHub <noreply@github.com>2024-05-15 11:49:07 -0700
commitbf7b66d5c1c0d7f7bdcc1c1aa43b6881d797d1e8 (patch)
treedfbbd3babc73b4251883b8dc786b1dbea7f08c1a /modules/BlueskyNSE
parent31868b255f7be001821e03033b3bdd1070ea28cf (diff)
downloadvoidsky-bf7b66d5c1c0d7f7bdcc1c1aa43b6881d797d1e8.tar.zst
Add push notification extensions (#4005)
* add wav

* add sound to config

* add extension to `updateExtensions.sh`

* add ios source files

* add a build extension

* add a new module

* use correct type on ios

* update the build plugin

* add android handler

* create a patch for expo-notifications

* basic android implementation

* add entitlements for notifications extension

* add some generic logic for ios

* add age check logic

* add extension to app config

* remove dash

* move directory

* rename again

* update privacy manifest

* add prefs storage ios

* better types

* create interface for setting and getting prefs

* add notifications prefs for android

* add functions to module

* add types to js

* add prefs context

* add web stub

* wrap the app

* fix types

* more preferences for ios

* add a test toggle

* swap vars

* update patch

* fix patch error

* fix typo

* sigh

* sigh

* get stored prefs on launch

* anotehr type

* simplify

* about finished

* comment

* adjust plugin

* use supported file types

* update NSE

* futureproof ios

* futureproof android

* update sound file name

* handle initialization

* more cleanup

* update js types

* strict js types

* set the notification channel

* rm

* add silent channel

* add mute logic

* update patch

* podfile

* adjust channels

* fix android channel

* update readme

* oreo or higher

* nit

* don't use getValue

* nit
Diffstat (limited to 'modules/BlueskyNSE')
-rw-r--r--modules/BlueskyNSE/BlueskyNSE.entitlements10
-rw-r--r--modules/BlueskyNSE/Info.plist29
-rw-r--r--modules/BlueskyNSE/NotificationService.swift51
3 files changed, 90 insertions, 0 deletions
diff --git a/modules/BlueskyNSE/BlueskyNSE.entitlements b/modules/BlueskyNSE/BlueskyNSE.entitlements
new file mode 100644
index 000000000..4954bdb33
--- /dev/null
+++ b/modules/BlueskyNSE/BlueskyNSE.entitlements
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+  <dict>
+    <key>com.apple.security.application-groups</key>
+    <array>
+      <string>group.app.bsky</string>
+    </array>
+  </dict>
+</plist>
\ No newline at end of file
diff --git a/modules/BlueskyNSE/Info.plist b/modules/BlueskyNSE/Info.plist
new file mode 100644
index 000000000..c2dd7eda6
--- /dev/null
+++ b/modules/BlueskyNSE/Info.plist
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+  <dict>
+    <key>NSExtension</key>
+    <dict>
+      <key>NSExtensionPointIdentifier</key>
+      <string>com.apple.usernotifications.service</string>
+      <key>NSExtensionPrincipalClass</key>
+      <string>$(PRODUCT_MODULE_NAME).NotificationService</string>
+    </dict>
+    <key>MainAppScheme</key>
+    <string>bluesky</string>
+    <key>CFBundleName</key>
+    <string>$(PRODUCT_NAME)</string>
+    <key>CFBundleDisplayName</key>
+    <string>Bluesky Notifications</string>
+    <key>CFBundleIdentifier</key>
+    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+    <key>CFBundleVersion</key>
+    <string>$(CURRENT_PROJECT_VERSION)</string>
+    <key>CFBundleExecutable</key>
+    <string>$(EXECUTABLE_NAME)</string>
+    <key>CFBundlePackageType</key>
+    <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
+    <key>CFBundleShortVersionString</key>
+    <string>$(MARKETING_VERSION)</string>
+  </dict>
+</plist>
\ No newline at end of file
diff --git a/modules/BlueskyNSE/NotificationService.swift b/modules/BlueskyNSE/NotificationService.swift
new file mode 100644
index 000000000..c6f391e00
--- /dev/null
+++ b/modules/BlueskyNSE/NotificationService.swift
@@ -0,0 +1,51 @@
+import UserNotifications
+
+let APP_GROUP = "group.app.bsky"
+
+class NotificationService: UNNotificationServiceExtension {
+  var prefs = UserDefaults(suiteName: APP_GROUP)
+
+  override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
+    guard var bestAttempt = createCopy(request.content),
+          let reason = request.content.userInfo["reason"] as? String
+    else {
+      contentHandler(request.content)
+      return
+    }
+    
+    if reason == "chat-message" {
+      mutateWithChatMessage(bestAttempt)
+    }
+    
+    // The badge should always be incremented when in the background
+    mutateWithBadge(bestAttempt)
+    
+    contentHandler(bestAttempt)
+  }
+  
+  override func serviceExtensionTimeWillExpire() {
+    // If for some reason the alloted time expires, we don't actually want to display a notification
+  }
+  
+  func createCopy(_ content: UNNotificationContent) -> UNMutableNotificationContent? {
+    return content.mutableCopy() as? UNMutableNotificationContent
+  }
+  
+  func mutateWithBadge(_ content: UNMutableNotificationContent) {
+    content.badge = 1
+  }
+  
+  func mutateWithChatMessage(_ content: UNMutableNotificationContent) {
+    if self.prefs?.bool(forKey: "playSoundChat") == true {
+      mutateWithDmSound(content)
+    }
+  }
+  
+  func mutateWithDefaultSound(_ content: UNMutableNotificationContent) {
+    content.sound = UNNotificationSound.default
+  }
+  
+  func mutateWithDmSound(_ content: UNMutableNotificationContent) {
+    content.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: "dm.aiff"))
+  }
+}