diff --git a/modules/BlueskyNSE/NotificationService.swift b/modules/BlueskyNSE/NotificationService.swift index e6aca99c..384180d8 100644 --- a/modules/BlueskyNSE/NotificationService.swift +++ b/modules/BlueskyNSE/NotificationService.swift @@ -1,4 +1,5 @@ import UserNotifications +import UIKit let APP_GROUP = "group.app.bsky" @@ -31,7 +32,12 @@ class NotificationService: UNNotificationServiceExtension { } func mutateWithBadge(_ content: UNMutableNotificationContent) { - content.badge = 1 + var count = prefs?.integer(forKey: "badgeCount") ?? 0 + count += 1 + + // Set the new badge number for the notification, then store that value for using later + content.badge = NSNumber(value: count) + prefs?.setValue(count, forKey: "badgeCount") } func mutateWithChatMessage(_ content: UNMutableNotificationContent) { diff --git a/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/ExpoBackgroundNotificationHandlerModule.kt b/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/ExpoBackgroundNotificationHandlerModule.kt index 083ff122..c876f899 100644 --- a/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/ExpoBackgroundNotificationHandlerModule.kt +++ b/modules/expo-background-notification-handler/android/src/main/java/expo/modules/backgroundnotificationhandler/ExpoBackgroundNotificationHandlerModule.kt @@ -66,5 +66,9 @@ class ExpoBackgroundNotificationHandlerModule : Module() { AsyncFunction("removeManyFromStringArrayAsync") { forKey: String, strings: Array -> NotificationPrefs(appContext.reactContext).removeManyFromStringArray(forKey, strings) } + + AsyncFunction("setBadgeCountAsync") { _: Int -> + // This does nothing on Android + } } } diff --git a/modules/expo-background-notification-handler/ios/ExpoBackgroundNotificationHandlerModule.swift b/modules/expo-background-notification-handler/ios/ExpoBackgroundNotificationHandlerModule.swift index 08972a04..5f8c7fc3 100644 --- a/modules/expo-background-notification-handler/ios/ExpoBackgroundNotificationHandlerModule.swift +++ b/modules/expo-background-notification-handler/ios/ExpoBackgroundNotificationHandlerModule.swift @@ -10,7 +10,8 @@ let DEFAULTS: [String:Any] = [ "playSoundQuote": false, "playSoundReply": false, "playSoundRepost": false, - "mutedThreads": [:] as! [String:[String]] + "mutedThreads": [:] as! [String:[String]], + "badgeCount": 0, ] /* @@ -112,5 +113,9 @@ public class ExpoBackgroundNotificationHandlerModule: Module { userDefaults?.setValue(curr, forKey: forKey) } } + + AsyncFunction("setBadgeCountAsync") { (count: Int) in + userDefaults?.setValue(count, forKey: "badgeCount") + } } } diff --git a/modules/expo-background-notification-handler/src/ExpoBackgroundNotificationHandler.types.ts b/modules/expo-background-notification-handler/src/ExpoBackgroundNotificationHandler.types.ts index 5fbd302d..b74148db 100644 --- a/modules/expo-background-notification-handler/src/ExpoBackgroundNotificationHandler.types.ts +++ b/modules/expo-background-notification-handler/src/ExpoBackgroundNotificationHandler.types.ts @@ -31,6 +31,7 @@ export type ExpoBackgroundNotificationHandlerModule = { forKey: keyof BackgroundNotificationHandlerPreferences, value: string[], ) => Promise + setBadgeCountAsync: (count: number) => Promise } // TODO there are more preferences in the native code, however they have not been added here yet. diff --git a/modules/expo-background-notification-handler/src/ExpoBackgroundNotificationHandlerModule.web.ts b/modules/expo-background-notification-handler/src/ExpoBackgroundNotificationHandlerModule.web.ts index 29e27fd0..893548e1 100644 --- a/modules/expo-background-notification-handler/src/ExpoBackgroundNotificationHandlerModule.web.ts +++ b/modules/expo-background-notification-handler/src/ExpoBackgroundNotificationHandlerModule.web.ts @@ -24,4 +24,5 @@ export const BackgroundNotificationHandler = { removeFromStringArrayAsync: async (_: string, __: string) => {}, addManyToStringArrayAsync: async (_: string, __: string[]) => {}, removeManyFromStringArrayAsync: async (_: string, __: string[]) => {}, + setBadgeCountAsync: async (_: number) => {}, } as ExpoBackgroundNotificationHandlerModule diff --git a/src/lib/notifications/notifications.ts b/src/lib/notifications/notifications.ts index 705d90c5..55a7948e 100644 --- a/src/lib/notifications/notifications.ts +++ b/src/lib/notifications/notifications.ts @@ -7,6 +7,7 @@ import {logger} from '#/logger' import {SessionAccount, useAgent, useSession} from '#/state/session' import {logEvent, useGate} from 'lib/statsig/statsig' import {devicePlatform, isNative} from 'platform/detection' +import BackgroundNotificationHandler from '../../../modules/expo-background-notification-handler' const SERVICE_DID = (serviceUrl?: string) => serviceUrl?.includes('staging') @@ -108,19 +109,20 @@ export function useRequestNotificationsPermission() { } } -export async function decrementBadgeCount(by: number | 'reset' = 1) { +export async function decrementBadgeCount(by: number) { if (!isNative) return - const currCount = await getBadgeCountAsync() - - if (by === 'reset') { - await setBadgeCountAsync(0) - return + let count = await getBadgeCountAsync() + count -= by + if (count < 0) { + count = 0 } - let newCount = currCount - by - if (newCount < 0) { - newCount = 0 - } - await setBadgeCountAsync(newCount) + await BackgroundNotificationHandler.setBadgeCountAsync(count) + await setBadgeCountAsync(count) +} + +export async function resetBadgeCount() { + await BackgroundNotificationHandler.setBadgeCountAsync(0) + await setBadgeCountAsync(0) } diff --git a/src/state/queries/notifications/unread.tsx b/src/state/queries/notifications/unread.tsx index 5f33cdf7..ffb8d03b 100644 --- a/src/state/queries/notifications/unread.tsx +++ b/src/state/queries/notifications/unread.tsx @@ -11,7 +11,7 @@ import BroadcastChannel from '#/lib/broadcast' import {logger} from '#/logger' import {useMutedThreads} from '#/state/muted-threads' import {useAgent, useSession} from '#/state/session' -import {decrementBadgeCount} from 'lib/notifications/notifications' +import {resetBadgeCount} from 'lib/notifications/notifications' import {useModerationOpts} from '../../preferences/moderation-opts' import {truncateAndInvalidate} from '../util' import {RQKEY as RQKEY_NOTIFS} from './feed' @@ -119,7 +119,7 @@ export function Provider({children}: React.PropsWithChildren<{}>) { // update & broadcast setNumUnread('') broadcast.postMessage({event: ''}) - decrementBadgeCount('reset') + resetBadgeCount() }, async checkUnread({