mirror of https://git.lenooby09.tech/LeNooby09/social-app.git
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at session/schema 151 lines 5.0 kB view raw
1import {useEffect} from 'react' 2import * as Notifications from 'expo-notifications' 3import {BskyAgent} from '@atproto/api' 4import {QueryClient} from '@tanstack/react-query' 5 6import {logger} from '#/logger' 7import {RQKEY as RQKEY_NOTIFS} from '#/state/queries/notifications/feed' 8import {invalidateCachedUnreadPage} from '#/state/queries/notifications/unread' 9import {truncateAndInvalidate} from '#/state/queries/util' 10import {SessionAccount} from '#/state/session' 11import {track} from 'lib/analytics/analytics' 12import {devicePlatform, isIOS} from 'platform/detection' 13import {resetToTab} from '../../Navigation' 14import {logEvent} from '../statsig/statsig' 15 16const SERVICE_DID = (serviceUrl?: string) => 17 serviceUrl?.includes('staging') 18 ? 'did:web:api.staging.bsky.dev' 19 : 'did:web:api.bsky.app' 20 21export async function requestPermissionsAndRegisterToken( 22 getAgent: () => BskyAgent, 23 account: SessionAccount, 24) { 25 // request notifications permission once the user has logged in 26 const perms = await Notifications.getPermissionsAsync() 27 if (!perms.granted) { 28 await Notifications.requestPermissionsAsync() 29 } 30 31 // register the push token with the server 32 const token = await Notifications.getDevicePushTokenAsync() 33 try { 34 await getAgent().api.app.bsky.notification.registerPush({ 35 serviceDid: SERVICE_DID(account.service), 36 platform: devicePlatform, 37 token: token.data, 38 appId: 'xyz.blueskyweb.app', 39 }) 40 logger.debug( 41 'Notifications: Sent push token (init)', 42 { 43 tokenType: token.type, 44 token: token.data, 45 }, 46 logger.DebugContext.notifications, 47 ) 48 } catch (error) { 49 logger.error('Notifications: Failed to set push token', {message: error}) 50 } 51} 52 53export function registerTokenChangeHandler( 54 getAgent: () => BskyAgent, 55 account: SessionAccount, 56): () => void { 57 // listens for new changes to the push token 58 // 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. 59 const sub = Notifications.addPushTokenListener(async newToken => { 60 logger.debug( 61 'Notifications: Push token changed', 62 {tokenType: newToken.data, token: newToken.type}, 63 logger.DebugContext.notifications, 64 ) 65 try { 66 await getAgent().api.app.bsky.notification.registerPush({ 67 serviceDid: SERVICE_DID(account.service), 68 platform: devicePlatform, 69 token: newToken.data, 70 appId: 'xyz.blueskyweb.app', 71 }) 72 logger.debug( 73 'Notifications: Sent push token (event)', 74 { 75 tokenType: newToken.type, 76 token: newToken.data, 77 }, 78 logger.DebugContext.notifications, 79 ) 80 } catch (error) { 81 logger.error('Notifications: Failed to set push token', {message: error}) 82 } 83 }) 84 return () => { 85 sub.remove() 86 } 87} 88 89export function useNotificationsListener(queryClient: QueryClient) { 90 useEffect(() => { 91 // handle notifications that are received, both in the foreground or background 92 // NOTE: currently just here for debug logging 93 const sub1 = Notifications.addNotificationReceivedListener(event => { 94 invalidateCachedUnreadPage() 95 logger.debug( 96 'Notifications: received', 97 {event}, 98 logger.DebugContext.notifications, 99 ) 100 if (event.request.trigger.type === 'push') { 101 // handle payload-based deeplinks 102 let payload 103 if (isIOS) { 104 payload = event.request.trigger.payload 105 } else { 106 // TODO: handle android payload deeplink 107 } 108 if (payload) { 109 logger.debug( 110 'Notifications: received payload', 111 payload, 112 logger.DebugContext.notifications, 113 ) 114 // TODO: deeplink notif here 115 } 116 } 117 }) 118 119 // handle notifications that are tapped on 120 const sub2 = Notifications.addNotificationResponseReceivedListener( 121 response => { 122 logger.debug( 123 'Notifications: response received', 124 { 125 actionIdentifier: response.actionIdentifier, 126 }, 127 logger.DebugContext.notifications, 128 ) 129 if ( 130 response.actionIdentifier === Notifications.DEFAULT_ACTION_IDENTIFIER 131 ) { 132 logger.debug( 133 'User pressed a notification, opening notifications tab', 134 {}, 135 logger.DebugContext.notifications, 136 ) 137 track('Notificatons:OpenApp') 138 logEvent('notifications:openApp', {}) 139 invalidateCachedUnreadPage() 140 truncateAndInvalidate(queryClient, RQKEY_NOTIFS()) 141 resetToTab('NotificationsTab') // open notifications tab 142 } 143 }, 144 ) 145 146 return () => { 147 sub1.remove() 148 sub2.remove() 149 } 150 }, [queryClient]) 151}