1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
import * as Notifications from 'expo-notifications'
import {RootStoreModel} from '../../state'
import {resetToTab} from '../../Navigation'
import {devicePlatform, isIOS} from 'platform/detection'
import {track} from 'lib/analytics/analytics'
const SERVICE_DID = (serviceUrl?: string) =>
serviceUrl?.includes('staging')
? 'did:web:api.staging.bsky.dev'
: '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: SERVICE_DID(store.session.data?.service),
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: SERVICE_DID(store.session.data?.service),
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',
)
track('Notificatons:OpenApp')
resetToTab('NotificationsTab')
}
},
)
return () => {
sub.remove()
}
}
export function getPushToken() {
return Notifications.getDevicePushTokenAsync()
}
|