diff options
author | Ansh <anshnanda10@gmail.com> | 2023-08-23 16:28:51 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-23 16:28:51 -0700 |
commit | 8ab5eb6583b6ddd4ed03ef2b1a55ef83fa0c0625 (patch) | |
tree | 06ab22c1f0faf121f1de89247ccc43bf353408c7 /src/lib/notifications | |
parent | 32b9648931589311667423ce377ee42a1c78a84f (diff) | |
download | voidsky-8ab5eb6583b6ddd4ed03ef2b1a55ef83fa0c0625.tar.zst |
[APP-786] Native notifications (#1095)
* move `notifee.ts` to notifications folder * install expo notifications * add UIBackgroundMode `remote-notifications` to app.json * fix notifee import in Debug.tsx * add `google-services.json` * add `development-device` class to eas.json * Add `notifications.ts` for native notification handling * send push token to server * update `@atproto/api` * fix putting notif token to server * fix how push token is uploaded * fix lint * enable debug appview proxy header on all platforms * setup `notifications.ts` to work with app view notifs * clean up notification handler * add comments * update packages to correct versions * remove notifee * clean up code a lil * rename push token endpoint * remove unnecessary comments * fix comments * Remove old background scheduler * Fixes to push notifications API use * Bump @atproto/api@0.6.6 --------- Co-authored-by: Paul Frazee <pfrazee@gmail.com>
Diffstat (limited to 'src/lib/notifications')
-rw-r--r-- | src/lib/notifications/notifications.ts | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/src/lib/notifications/notifications.ts b/src/lib/notifications/notifications.ts new file mode 100644 index 000000000..b517b40bf --- /dev/null +++ b/src/lib/notifications/notifications.ts @@ -0,0 +1,101 @@ +import * as Notifications from 'expo-notifications' +import {RootStoreModel} from '../../state' +import {resetToTab} from '../../Navigation' +import {devicePlatform, isIOS} from 'platform/detection' + +// TODO prod did = did:web:api.bsky.app + +export function init(store: RootStoreModel) { + store.onUnreadNotifications(count => Notifications.setBadgeCountAsync(count)) + + store.onSessionLoaded(async () => { + // request notifications permission once the user has logged in + const perms = await Notifications.getPermissionsAsync() + if (!perms.granted) { + await Notifications.requestPermissionsAsync() + } + + // register the push token with the server + const token = await getPushToken() + if (token) { + try { + await store.agent.api.app.bsky.notification.registerPush({ + serviceDid: 'did:web:api.staging.bsky.dev', + platform: devicePlatform, + token: token.data, + appId: 'xyz.blueskyweb.app', + }) + store.log.debug('Notifications: Sent push token (init)', { + type: token.type, + token: token.data, + }) + } catch (error) { + store.log.error('Notifications: Failed to set push token', error) + } + } + + // listens for new changes to the push token + // In rare situations, a push token may be changed by the push notification service while the app is running. When a token is rolled, the old one becomes invalid and sending notifications to it will fail. A push token listener will let you handle this situation gracefully by registering the new token with your backend right away. + Notifications.addPushTokenListener(async ({data: t, type}) => { + store.log.debug('Notifications: Push token changed', {t, type}) + if (t) { + try { + await store.agent.api.app.bsky.notification.registerPush({ + serviceDid: 'did:web:api.staging.bsky.dev', + platform: devicePlatform, + token: t, + appId: 'xyz.blueskyweb.app', + }) + store.log.debug('Notifications: Sent push token (event)', { + type, + token: t, + }) + } catch (error) { + store.log.error('Notifications: Failed to set push token', error) + } + } + }) + }) + + // handle notifications that are tapped on, regardless of whether the app is in the foreground or background + Notifications.addNotificationReceivedListener(event => { + store.log.debug('Notifications: received', event) + if (event.request.trigger.type === 'push') { + let payload + if (isIOS) { + payload = event.request.trigger.payload + } else { + // TODO: handle android payload deeplink + } + if (payload) { + store.log.debug('Notifications: received payload', payload) + // TODO: deeplink notif here + } + } + }) + + const sub = Notifications.addNotificationResponseReceivedListener( + response => { + store.log.debug( + 'Notifications: response received', + response.actionIdentifier, + ) + if ( + response.actionIdentifier === Notifications.DEFAULT_ACTION_IDENTIFIER + ) { + store.log.debug( + 'User pressed a notification, opening notifications tab', + ) + resetToTab('NotificationsTab') + } + }, + ) + + return () => { + sub.remove() + } +} + +export function getPushToken() { + return Notifications.getDevicePushTokenAsync() +} |