@knocklabs/expo 0.1.0 → 0.2.1-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @knocklabs/expo
2
2
 
3
+ ## 0.2.1-rc.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [f442962]
8
+ - @knocklabs/react-core@0.3.0-rc.0
9
+ - @knocklabs/client@0.11.0-rc.0
10
+ - @knocklabs/react-native@0.5.1-rc.0
11
+
12
+ ## 0.2.0
13
+
14
+ ### Minor Changes
15
+
16
+ - 4ac1e67: Add KnockPushNotificationProvider
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies [4ac1e67]
21
+ - @knocklabs/react-native@0.5.0
22
+
3
23
  ## 0.1.0
4
24
 
5
25
  ### Minor Changes
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const w=require("react/jsx-runtime"),_=require("@knocklabs/react-core"),j=require("expo-constants"),D=require("expo-device"),R=require("expo-notifications"),i=require("react"),q=e=>e&&typeof e=="object"&&"default"in e?e:{default:e};function C(e){if(e&&typeof e=="object"&&"default"in e)return e;const a=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const c in e)if(c!=="default"){const l=Object.getOwnPropertyDescriptor(e,c);Object.defineProperty(a,c,l.get?l:{enumerable:!0,get:()=>e[c]})}}return a.default=e,Object.freeze(a)}const h=q(j),O=C(D),r=C(R);r.setNotificationHandler({handleNotification:async()=>({shouldShowAlert:!0,shouldPlaySound:!0,shouldSetBadge:!0})});const A=async e=>({shouldShowAlert:!0,shouldPlaySound:!0,shouldSetBadge:!0}),x=i.createContext(void 0);async function H(){const{status:e}=await r.getPermissionsAsync();if(e!=="granted"){const{status:a}=await r.requestPermissionsAsync();return a}return e}async function F(){try{return!h.default.expoConfig||!h.default.expoConfig.extra||!h.default.expoConfig.extra.eas?(console.error("[Knock] Expo Project ID is not defined in the app configuration."),null):await r.getExpoPushTokenAsync({projectId:h.default.expoConfig.extra.eas.projectId})}catch(e){return console.error("[Knock] Error getting Expo push token:",e),null}}async function M(){return O.isDevice?await H()!=="granted"?(console.warn("[Knock] Push notification permission not granted"),null):F():(console.warn("[Knock] Must use physical device for Push Notifications"),null)}const B=({knockExpoChannelId:e,customNotificationHandler:a,children:c,autoRegister:l=!0})=>{const[d,m]=i.useState(null),n=_.useKnockClient(),[g,v]=i.useState(()=>()=>{}),[k,y]=i.useState(()=>()=>{}),S=i.useCallback(t=>{v(()=>t)},[]),b=i.useCallback(t=>{y(()=>t)},[]),p=i.useCallback(async()=>{try{n.log("[Knock] Registering for push notifications");const t=await M();n.log(`[Knock] Token received: ${t==null?void 0:t.data}`),t!=null&&t.data&&(n.log(`[Knock] Setting push token: ${t.data}`),m(t.data))}catch(t){console.error("[Knock] Error registering for push notifications:",t)}},[n]),P=i.useCallback(async(t,s)=>{const o=t.request.content.data.knock_message_id;return n.messages.updateStatus(o,s)},[n]),u=i.useCallback(async(t,s)=>n.user.setChannelData({channelId:s,channelData:{tokens:t}}),[n]),N=i.useCallback(async(t,s)=>{n.user.getChannelData({channelId:s}).then(o=>{const f=o.data.tokens;if(!f.includes(t))return f.push(t),u(f,s);n.log("[Knock] registerPushTokenToChannel success")}).catch(o=>u([t],s))},[n,u]),K=i.useCallback(async(t,s)=>{n.user.getChannelData({channelId:s}).then(o=>{const T=o.data.tokens.filter(E=>E!==t);return n.log("unregisterPushTokenFromChannel success"),u(T,s)}).catch(o=>{console.error("[Knock] Error unregistering push token from channel:",o)})},[n,u]);return i.useEffect(()=>{r.setNotificationHandler({handleNotification:a??A}),l&&p().then(()=>{d&&N(d,e).then(o=>{n.log("[Knock] setChannelData success")}).catch(o=>{console.error("[Knock] Error in setting push token or channel data",o)})}).catch(o=>{console.error("[Knock] Error in setting push token or channel data",o)});const t=r.addNotificationReceivedListener(o=>{n.log("[Knock] Expo Push Notification received in foreground:"),P(o,"interacted"),g(o)}),s=r.addNotificationResponseReceivedListener(o=>{n.log("[Knock] Expo Push Notification was interacted with"),P(o.notification,"interacted"),k(o)});return()=>{r.removeNotificationSubscription(t),r.removeNotificationSubscription(s)}},[p,g,k,a,d,e,n]),w.jsx(x.Provider,{value:{expoPushToken:d,registerForPushNotifications:p,registerPushTokenToChannel:N,unregisterPushTokenFromChannel:K,onNotificationReceived:S,onNotificationTapped:b},children:c})},L=()=>{const e=i.useContext(x);if(e===void 0)throw new Error("[Knock] useExpoPushNotifications must be used within a PushNotificationProvider");return e};exports.KnockExpoPushNotificationProvider=B;exports.useExpoPushNotifications=L;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("react/jsx-runtime"),b=require("@knocklabs/react-core"),N=require("@knocklabs/react-native"),w=require("expo-constants"),T=require("expo-device"),j=require("expo-notifications"),i=require("react"),_=t=>t&&typeof t=="object"&&"default"in t?t:{default:t};function x(t){if(t&&typeof t=="object"&&"default"in t)return t;const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const c in t)if(c!=="default"){const a=Object.getOwnPropertyDescriptor(t,c);Object.defineProperty(r,c,a.get?a:{enumerable:!0,get:()=>t[c]})}}return r.default=t,Object.freeze(r)}const d=_(w),q=x(T),s=x(j);s.setNotificationHandler({handleNotification:async()=>({shouldShowAlert:!0,shouldPlaySound:!0,shouldSetBadge:!0})});const R=async t=>({shouldShowAlert:!0,shouldPlaySound:!0,shouldSetBadge:!0}),v=i.createContext(void 0);async function D(){const{status:t}=await s.getPermissionsAsync();if(t!=="granted"){const{status:r}=await s.requestPermissionsAsync();return r}return t}async function A(){try{return!d.default.expoConfig||!d.default.expoConfig.extra||!d.default.expoConfig.extra.eas?(console.error("[Knock] Expo Project ID is not defined in the app configuration."),null):await s.getExpoPushTokenAsync({projectId:d.default.expoConfig.extra.eas.projectId})}catch(t){return console.error("[Knock] Error getting Expo push token:",t),null}}async function H(){return q.isDevice?await D()!=="granted"?(console.warn("[Knock] Push notification permission not granted"),null):A():(console.warn("[Knock] Must use physical device for Push Notifications"),null)}const O=({knockExpoChannelId:t,customNotificationHandler:r,children:c,autoRegister:a=!0})=>{const{registerPushTokenToChannel:h,unregisterPushTokenFromChannel:m}=N.usePushNotifications(),[u,S]=i.useState(null),n=b.useKnockClient(),[g,y]=i.useState(()=>()=>{}),[k,K]=i.useState(()=>()=>{}),C=i.useCallback(e=>{y(()=>e)},[]),E=i.useCallback(e=>{K(()=>e)},[]),f=i.useCallback(async()=>{try{n.log("[Knock] Registering for push notifications");const e=await H();n.log(`[Knock] Token received: ${e==null?void 0:e.data}`),e!=null&&e.data&&(n.log(`[Knock] Setting push token: ${e.data}`),S(e.data))}catch(e){console.error("[Knock] Error registering for push notifications:",e)}},[n]),P=i.useCallback(async(e,l)=>{const o=e.request.content.data.knock_message_id;return n.messages.updateStatus(o,l)},[n]);return i.useEffect(()=>{s.setNotificationHandler({handleNotification:r??R}),a&&f().then(()=>{u&&h(u,t).then(o=>{n.log("[Knock] setChannelData success")}).catch(o=>{console.error("[Knock] Error in setting push token or channel data",o)})}).catch(o=>{console.error("[Knock] Error in setting push token or channel data",o)});const e=s.addNotificationReceivedListener(o=>{n.log("[Knock] Expo Push Notification received in foreground:"),P(o,"interacted"),g(o)}),l=s.addNotificationResponseReceivedListener(o=>{n.log("[Knock] Expo Push Notification was interacted with"),P(o.notification,"interacted"),k(o)});return()=>{s.removeNotificationSubscription(e),s.removeNotificationSubscription(l)}},[f,g,k,r,u,t,n]),p.jsx(v.Provider,{value:{expoPushToken:u,registerForPushNotifications:f,registerPushTokenToChannel:h,unregisterPushTokenFromChannel:m,onNotificationReceived:C,onNotificationTapped:E},children:c})},I=t=>p.jsx(N.KnockPushNotificationProvider,{children:p.jsx(O,{...t})}),M=()=>{const t=i.useContext(v);if(t===void 0)throw new Error("[Knock] useExpoPushNotifications must be used within a KnockExpoPushNotificationProvider");return t};exports.KnockExpoPushNotificationProvider=I;exports.useExpoPushNotifications=M;
2
2
  //# sourceMappingURL=KnockExpoPushNotificationProvider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"KnockExpoPushNotificationProvider.js","sources":["../../../../src/modules/push/KnockExpoPushNotificationProvider.tsx"],"sourcesContent":["import {\n ChannelData,\n Message,\n MessageEngagementStatus,\n} from \"@knocklabs/client\";\nimport { useKnockClient } from \"@knocklabs/react-core\";\nimport Constants from \"expo-constants\";\nimport * as Device from \"expo-device\";\nimport * as Notifications from \"expo-notifications\";\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from \"react\";\n\nexport interface KnockExpoPushNotificationContextType {\n expoPushToken: string | null;\n registerForPushNotifications: () => Promise<void>;\n registerPushTokenToChannel(token: string, channelId: string): Promise<void>;\n unregisterPushTokenFromChannel(\n token: string,\n channelId: string,\n ): Promise<void>;\n onNotificationReceived: (\n handler: (notification: Notifications.Notification) => void,\n ) => void;\n onNotificationTapped: (\n handler: (response: Notifications.NotificationResponse) => void,\n ) => void;\n}\n\nNotifications.setNotificationHandler({\n handleNotification: async () => {\n return {\n shouldShowAlert: true,\n shouldPlaySound: true,\n shouldSetBadge: true,\n };\n },\n});\n\nconst defaultNotificationHandler = async (\n _notification: Notifications.Notification,\n): Promise<Notifications.NotificationBehavior> => {\n return {\n shouldShowAlert: true,\n shouldPlaySound: true,\n shouldSetBadge: true,\n };\n};\n\nconst KnockExpoPushNotificationContext = createContext<\n KnockExpoPushNotificationContextType | undefined\n>(undefined);\n\nexport interface KnockExpoPushNotificationProviderProps {\n knockExpoChannelId: string;\n customNotificationHandler?: (\n notification: Notifications.Notification,\n ) => Promise<Notifications.NotificationBehavior>;\n children?: React.ReactElement;\n autoRegister?: boolean;\n}\n\nasync function requestPushPermissionIfNeeded(): Promise<string> {\n const { status: existingStatus } = await Notifications.getPermissionsAsync();\n\n if (existingStatus !== \"granted\") {\n const { status } = await Notifications.requestPermissionsAsync();\n return status;\n }\n\n return existingStatus;\n}\n\nasync function getExpoPushToken(): Promise<Notifications.ExpoPushToken | null> {\n try {\n if (\n !Constants.expoConfig ||\n !Constants.expoConfig.extra ||\n !Constants.expoConfig.extra.eas\n ) {\n console.error(\n \"[Knock] Expo Project ID is not defined in the app configuration.\",\n );\n return null;\n }\n const token = await Notifications.getExpoPushTokenAsync({\n projectId: Constants.expoConfig.extra.eas.projectId,\n });\n return token;\n } catch (error) {\n console.error(\"[Knock] Error getting Expo push token:\", error);\n return null;\n }\n}\n\nasync function requestPermissionAndGetPushToken(): Promise<Notifications.ExpoPushToken | null> {\n // Check for device support\n if (!Device.isDevice) {\n console.warn(\"[Knock] Must use physical device for Push Notifications\");\n return null;\n }\n\n const permissionStatus = await requestPushPermissionIfNeeded();\n\n if (permissionStatus !== \"granted\") {\n console.warn(\"[Knock] Push notification permission not granted\");\n return null;\n }\n\n return getExpoPushToken();\n}\n\nexport const KnockExpoPushNotificationProvider: React.FC<\n KnockExpoPushNotificationProviderProps\n> = ({\n knockExpoChannelId,\n customNotificationHandler,\n children,\n autoRegister = true,\n}) => {\n const [expoPushToken, setExpoPushToken] = useState<string | null>(null);\n const knockClient = useKnockClient();\n\n const [notificationReceivedHandler, setNotificationReceivedHandler] =\n useState<(notification: Notifications.Notification) => void>(\n () => () => {},\n );\n\n const [notificationTappedHandler, setNotificationTappedHandler] = useState<\n (response: Notifications.NotificationResponse) => void\n >(() => () => {});\n\n const handleNotificationReceived = useCallback(\n (handler: (notification: Notifications.Notification) => void) => {\n setNotificationReceivedHandler(() => handler);\n },\n [],\n );\n\n const handleNotificationTapped = useCallback(\n (handler: (response: Notifications.NotificationResponse) => void) => {\n setNotificationTappedHandler(() => handler);\n },\n [],\n );\n\n const registerForPushNotifications = useCallback(async (): Promise<void> => {\n try {\n knockClient.log(`[Knock] Registering for push notifications`);\n const token = await requestPermissionAndGetPushToken();\n knockClient.log(`[Knock] Token received: ${token?.data}`);\n if (token?.data) {\n knockClient.log(`[Knock] Setting push token: ${token.data}`);\n setExpoPushToken(token.data);\n }\n } catch (error) {\n console.error(`[Knock] Error registering for push notifications:`, error);\n }\n }, [knockClient]);\n\n const updateKnockMessageStatusFromNotification = useCallback(\n async (\n notification: Notifications.Notification,\n status: MessageEngagementStatus,\n ): Promise<Message> => {\n const messageId = notification.request.content.data[\"knock_message_id\"];\n return knockClient.messages.updateStatus(messageId, status);\n },\n [knockClient],\n );\n\n const registerNewTokenDataOnServer = useCallback(\n async (tokens: string[], channelId: string): Promise<ChannelData> => {\n return knockClient.user.setChannelData({\n channelId: channelId,\n channelData: { tokens: tokens },\n });\n },\n [knockClient],\n );\n\n const registerPushTokenToChannel = useCallback(\n async (token: string, channelId: string): Promise<void> => {\n knockClient.user\n .getChannelData({ channelId: channelId })\n .then((result: ChannelData) => {\n const tokens: string[] = result.data[\"tokens\"];\n if (!tokens.includes(token)) {\n tokens.push(token);\n return registerNewTokenDataOnServer(tokens, channelId);\n }\n knockClient.log(\"[Knock] registerPushTokenToChannel success\");\n })\n .catch((_) => {\n // No data registered on that channel for that user, we'll create a new record\n return registerNewTokenDataOnServer([token], channelId);\n });\n },\n [knockClient, registerNewTokenDataOnServer],\n );\n\n const unregisterPushTokenFromChannel = useCallback(\n async (token: string, channelId: string): Promise<void> => {\n knockClient.user\n .getChannelData({ channelId: channelId })\n .then((result: ChannelData) => {\n const tokens: string[] = result.data[\"tokens\"];\n const updatedTokens = tokens.filter(\n (channelToken) => channelToken !== token,\n );\n knockClient.log(\"unregisterPushTokenFromChannel success\");\n return registerNewTokenDataOnServer(updatedTokens, channelId);\n })\n .catch((error) => {\n console.error(\n `[Knock] Error unregistering push token from channel:`,\n error,\n );\n });\n },\n [knockClient, registerNewTokenDataOnServer],\n );\n\n useEffect(() => {\n Notifications.setNotificationHandler({\n handleNotification:\n customNotificationHandler ?? defaultNotificationHandler,\n });\n\n if (autoRegister) {\n registerForPushNotifications()\n .then(() => {\n if (expoPushToken) {\n registerPushTokenToChannel(expoPushToken, knockExpoChannelId)\n .then((_result) => {\n knockClient.log(\"[Knock] setChannelData success\");\n })\n .catch((_error) => {\n console.error(\n \"[Knock] Error in setting push token or channel data\",\n _error,\n );\n });\n }\n })\n .catch((_error) => {\n console.error(\n \"[Knock] Error in setting push token or channel data\",\n _error,\n );\n });\n }\n\n const notificationReceivedSubscription =\n Notifications.addNotificationReceivedListener((notification) => {\n knockClient.log(\n \"[Knock] Expo Push Notification received in foreground:\",\n );\n updateKnockMessageStatusFromNotification(notification, \"interacted\");\n notificationReceivedHandler(notification);\n });\n\n const notificationResponseSubscription =\n Notifications.addNotificationResponseReceivedListener((response) => {\n knockClient.log(\"[Knock] Expo Push Notification was interacted with\");\n updateKnockMessageStatusFromNotification(\n response.notification,\n \"interacted\",\n );\n notificationTappedHandler(response);\n });\n\n return () => {\n Notifications.removeNotificationSubscription(\n notificationReceivedSubscription,\n );\n Notifications.removeNotificationSubscription(\n notificationResponseSubscription,\n );\n };\n\n // TODO: Remove when possible and ensure dependency array is correct\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n registerForPushNotifications,\n notificationReceivedHandler,\n notificationTappedHandler,\n customNotificationHandler,\n expoPushToken,\n knockExpoChannelId,\n knockClient,\n ]);\n\n return (\n <KnockExpoPushNotificationContext.Provider\n value={{\n expoPushToken,\n registerForPushNotifications,\n registerPushTokenToChannel,\n unregisterPushTokenFromChannel,\n onNotificationReceived: handleNotificationReceived,\n onNotificationTapped: handleNotificationTapped,\n }}\n >\n {children}\n </KnockExpoPushNotificationContext.Provider>\n );\n};\n\nexport const useExpoPushNotifications =\n (): KnockExpoPushNotificationContextType => {\n const context = useContext(KnockExpoPushNotificationContext);\n if (context === undefined) {\n throw new Error(\n \"[Knock] useExpoPushNotifications must be used within a PushNotificationProvider\",\n );\n }\n return context;\n };\n"],"names":["Notifications","defaultNotificationHandler","_notification","KnockExpoPushNotificationContext","createContext","requestPushPermissionIfNeeded","existingStatus","status","getExpoPushToken","Constants","error","requestPermissionAndGetPushToken","Device","KnockExpoPushNotificationProvider","knockExpoChannelId","customNotificationHandler","children","autoRegister","expoPushToken","setExpoPushToken","useState","knockClient","useKnockClient","notificationReceivedHandler","setNotificationReceivedHandler","notificationTappedHandler","setNotificationTappedHandler","handleNotificationReceived","useCallback","handler","handleNotificationTapped","registerForPushNotifications","token","updateKnockMessageStatusFromNotification","notification","messageId","registerNewTokenDataOnServer","tokens","channelId","registerPushTokenToChannel","result","_","unregisterPushTokenFromChannel","updatedTokens","channelToken","useEffect","_result","_error","notificationReceivedSubscription","notificationResponseSubscription","response","jsx","useExpoPushNotifications","context","useContext"],"mappings":"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"}
1
+ {"version":3,"file":"KnockExpoPushNotificationProvider.js","sources":["../../../../src/modules/push/KnockExpoPushNotificationProvider.tsx"],"sourcesContent":["import { Message, MessageEngagementStatus } from \"@knocklabs/client\";\nimport { useKnockClient } from \"@knocklabs/react-core\";\nimport {\n type KnockPushNotificationContextType,\n KnockPushNotificationProvider,\n usePushNotifications,\n} from \"@knocklabs/react-native\";\nimport Constants from \"expo-constants\";\nimport * as Device from \"expo-device\";\nimport * as Notifications from \"expo-notifications\";\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from \"react\";\n\nexport interface KnockExpoPushNotificationContextType\n extends KnockPushNotificationContextType {\n expoPushToken: string | null;\n registerForPushNotifications: () => Promise<void>;\n onNotificationReceived: (\n handler: (notification: Notifications.Notification) => void,\n ) => void;\n onNotificationTapped: (\n handler: (response: Notifications.NotificationResponse) => void,\n ) => void;\n}\n\nNotifications.setNotificationHandler({\n handleNotification: async () => {\n return {\n shouldShowAlert: true,\n shouldPlaySound: true,\n shouldSetBadge: true,\n };\n },\n});\n\nconst defaultNotificationHandler = async (\n _notification: Notifications.Notification,\n): Promise<Notifications.NotificationBehavior> => {\n return {\n shouldShowAlert: true,\n shouldPlaySound: true,\n shouldSetBadge: true,\n };\n};\n\nconst KnockExpoPushNotificationContext = createContext<\n KnockExpoPushNotificationContextType | undefined\n>(undefined);\n\nexport interface KnockExpoPushNotificationProviderProps {\n knockExpoChannelId: string;\n customNotificationHandler?: (\n notification: Notifications.Notification,\n ) => Promise<Notifications.NotificationBehavior>;\n children?: React.ReactElement;\n autoRegister?: boolean;\n}\n\nasync function requestPushPermissionIfNeeded(): Promise<string> {\n const { status: existingStatus } = await Notifications.getPermissionsAsync();\n\n if (existingStatus !== \"granted\") {\n const { status } = await Notifications.requestPermissionsAsync();\n return status;\n }\n\n return existingStatus;\n}\n\nasync function getExpoPushToken(): Promise<Notifications.ExpoPushToken | null> {\n try {\n if (\n !Constants.expoConfig ||\n !Constants.expoConfig.extra ||\n !Constants.expoConfig.extra.eas\n ) {\n console.error(\n \"[Knock] Expo Project ID is not defined in the app configuration.\",\n );\n return null;\n }\n const token = await Notifications.getExpoPushTokenAsync({\n projectId: Constants.expoConfig.extra.eas.projectId,\n });\n return token;\n } catch (error) {\n console.error(\"[Knock] Error getting Expo push token:\", error);\n return null;\n }\n}\n\nasync function requestPermissionAndGetPushToken(): Promise<Notifications.ExpoPushToken | null> {\n // Check for device support\n if (!Device.isDevice) {\n console.warn(\"[Knock] Must use physical device for Push Notifications\");\n return null;\n }\n\n const permissionStatus = await requestPushPermissionIfNeeded();\n\n if (permissionStatus !== \"granted\") {\n console.warn(\"[Knock] Push notification permission not granted\");\n return null;\n }\n\n return getExpoPushToken();\n}\n\nconst InternalKnockExpoPushNotificationProvider: React.FC<\n KnockExpoPushNotificationProviderProps\n> = ({\n knockExpoChannelId,\n customNotificationHandler,\n children,\n autoRegister = true,\n}) => {\n const { registerPushTokenToChannel, unregisterPushTokenFromChannel } =\n usePushNotifications();\n const [expoPushToken, setExpoPushToken] = useState<string | null>(null);\n const knockClient = useKnockClient();\n\n const [notificationReceivedHandler, setNotificationReceivedHandler] =\n useState<(notification: Notifications.Notification) => void>(\n () => () => {},\n );\n\n const [notificationTappedHandler, setNotificationTappedHandler] = useState<\n (response: Notifications.NotificationResponse) => void\n >(() => () => {});\n\n const handleNotificationReceived = useCallback(\n (handler: (notification: Notifications.Notification) => void) => {\n setNotificationReceivedHandler(() => handler);\n },\n [],\n );\n\n const handleNotificationTapped = useCallback(\n (handler: (response: Notifications.NotificationResponse) => void) => {\n setNotificationTappedHandler(() => handler);\n },\n [],\n );\n\n const registerForPushNotifications = useCallback(async (): Promise<void> => {\n try {\n knockClient.log(`[Knock] Registering for push notifications`);\n const token = await requestPermissionAndGetPushToken();\n knockClient.log(`[Knock] Token received: ${token?.data}`);\n if (token?.data) {\n knockClient.log(`[Knock] Setting push token: ${token.data}`);\n setExpoPushToken(token.data);\n }\n } catch (error) {\n console.error(`[Knock] Error registering for push notifications:`, error);\n }\n }, [knockClient]);\n\n const updateKnockMessageStatusFromNotification = useCallback(\n async (\n notification: Notifications.Notification,\n status: MessageEngagementStatus,\n ): Promise<Message> => {\n const messageId = notification.request.content.data[\"knock_message_id\"];\n return knockClient.messages.updateStatus(messageId, status);\n },\n [knockClient],\n );\n\n useEffect(() => {\n Notifications.setNotificationHandler({\n handleNotification:\n customNotificationHandler ?? defaultNotificationHandler,\n });\n\n if (autoRegister) {\n registerForPushNotifications()\n .then(() => {\n if (expoPushToken) {\n registerPushTokenToChannel(expoPushToken, knockExpoChannelId)\n .then((_result) => {\n knockClient.log(\"[Knock] setChannelData success\");\n })\n .catch((_error) => {\n console.error(\n \"[Knock] Error in setting push token or channel data\",\n _error,\n );\n });\n }\n })\n .catch((_error) => {\n console.error(\n \"[Knock] Error in setting push token or channel data\",\n _error,\n );\n });\n }\n\n const notificationReceivedSubscription =\n Notifications.addNotificationReceivedListener((notification) => {\n knockClient.log(\n \"[Knock] Expo Push Notification received in foreground:\",\n );\n updateKnockMessageStatusFromNotification(notification, \"interacted\");\n notificationReceivedHandler(notification);\n });\n\n const notificationResponseSubscription =\n Notifications.addNotificationResponseReceivedListener((response) => {\n knockClient.log(\"[Knock] Expo Push Notification was interacted with\");\n updateKnockMessageStatusFromNotification(\n response.notification,\n \"interacted\",\n );\n notificationTappedHandler(response);\n });\n\n return () => {\n Notifications.removeNotificationSubscription(\n notificationReceivedSubscription,\n );\n Notifications.removeNotificationSubscription(\n notificationResponseSubscription,\n );\n };\n\n // TODO: Remove when possible and ensure dependency array is correct\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n registerForPushNotifications,\n notificationReceivedHandler,\n notificationTappedHandler,\n customNotificationHandler,\n expoPushToken,\n knockExpoChannelId,\n knockClient,\n ]);\n\n return (\n <KnockExpoPushNotificationContext.Provider\n value={{\n expoPushToken,\n registerForPushNotifications,\n registerPushTokenToChannel,\n unregisterPushTokenFromChannel,\n onNotificationReceived: handleNotificationReceived,\n onNotificationTapped: handleNotificationTapped,\n }}\n >\n {children}\n </KnockExpoPushNotificationContext.Provider>\n );\n};\n\nexport const KnockExpoPushNotificationProvider: React.FC<\n KnockExpoPushNotificationProviderProps\n> = (props) => {\n return (\n <KnockPushNotificationProvider>\n <InternalKnockExpoPushNotificationProvider {...props} />\n </KnockPushNotificationProvider>\n );\n};\n\nexport const useExpoPushNotifications =\n (): KnockExpoPushNotificationContextType => {\n const context = useContext(KnockExpoPushNotificationContext);\n if (context === undefined) {\n throw new Error(\n \"[Knock] useExpoPushNotifications must be used within a KnockExpoPushNotificationProvider\",\n );\n }\n return context;\n };\n"],"names":["Notifications","defaultNotificationHandler","_notification","KnockExpoPushNotificationContext","createContext","requestPushPermissionIfNeeded","existingStatus","status","getExpoPushToken","Constants","error","requestPermissionAndGetPushToken","Device","InternalKnockExpoPushNotificationProvider","knockExpoChannelId","customNotificationHandler","children","autoRegister","registerPushTokenToChannel","unregisterPushTokenFromChannel","usePushNotifications","expoPushToken","setExpoPushToken","useState","knockClient","useKnockClient","notificationReceivedHandler","setNotificationReceivedHandler","notificationTappedHandler","setNotificationTappedHandler","handleNotificationReceived","useCallback","handler","handleNotificationTapped","registerForPushNotifications","token","updateKnockMessageStatusFromNotification","notification","messageId","useEffect","_result","_error","notificationReceivedSubscription","notificationResponseSubscription","response","jsx","KnockExpoPushNotificationProvider","props","KnockPushNotificationProvider","useExpoPushNotifications","context","useContext"],"mappings":"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"}
@@ -1,115 +1,85 @@
1
- import { jsx as R } from "react/jsx-runtime";
2
- import { useKnockClient as D } from "@knocklabs/react-core";
3
- import f from "expo-constants";
4
- import * as b from "expo-device";
5
- import * as s from "expo-notifications";
6
- import { createContext as A, useState as h, useCallback as r, useEffect as H, useContext as _ } from "react";
7
- s.setNotificationHandler({
1
+ import { jsx as l } from "react/jsx-runtime";
2
+ import { useKnockClient as w } from "@knocklabs/react-core";
3
+ import { KnockPushNotificationProvider as C, usePushNotifications as T } from "@knocklabs/react-native";
4
+ import c from "expo-constants";
5
+ import * as R from "expo-device";
6
+ import * as i from "expo-notifications";
7
+ import { createContext as b, useContext as A, useState as f, useCallback as a, useEffect as H } from "react";
8
+ i.setNotificationHandler({
8
9
  handleNotification: async () => ({
9
10
  shouldShowAlert: !0,
10
11
  shouldPlaySound: !0,
11
12
  shouldSetBadge: !0
12
13
  })
13
14
  });
14
- const j = async (n) => ({
15
+ const I = async (t) => ({
15
16
  shouldShowAlert: !0,
16
17
  shouldPlaySound: !0,
17
18
  shouldSetBadge: !0
18
- }), m = A(void 0);
19
- async function q() {
20
- const { status: n } = await s.getPermissionsAsync();
21
- if (n !== "granted") {
22
- const { status: c } = await s.requestPermissionsAsync();
23
- return c;
19
+ }), P = b(void 0);
20
+ async function j() {
21
+ const { status: t } = await i.getPermissionsAsync();
22
+ if (t !== "granted") {
23
+ const { status: r } = await i.requestPermissionsAsync();
24
+ return r;
24
25
  }
25
- return n;
26
+ return t;
26
27
  }
27
- async function F() {
28
+ async function q() {
28
29
  try {
29
- return !f.expoConfig || !f.expoConfig.extra || !f.expoConfig.extra.eas ? (console.error(
30
+ return !c.expoConfig || !c.expoConfig.extra || !c.expoConfig.extra.eas ? (console.error(
30
31
  "[Knock] Expo Project ID is not defined in the app configuration."
31
- ), null) : await s.getExpoPushTokenAsync({
32
- projectId: f.expoConfig.extra.eas.projectId
32
+ ), null) : await i.getExpoPushTokenAsync({
33
+ projectId: c.expoConfig.extra.eas.projectId
33
34
  });
34
- } catch (n) {
35
- return console.error("[Knock] Error getting Expo push token:", n), null;
35
+ } catch (t) {
36
+ return console.error("[Knock] Error getting Expo push token:", t), null;
36
37
  }
37
38
  }
38
- async function B() {
39
- return b.isDevice ? await q() !== "granted" ? (console.warn("[Knock] Push notification permission not granted"), null) : F() : (console.warn("[Knock] Must use physical device for Push Notifications"), null);
39
+ async function D() {
40
+ return R.isDevice ? await j() !== "granted" ? (console.warn("[Knock] Push notification permission not granted"), null) : q() : (console.warn("[Knock] Must use physical device for Push Notifications"), null);
40
41
  }
41
- const I = ({
42
- knockExpoChannelId: n,
43
- customNotificationHandler: c,
42
+ const _ = ({
43
+ knockExpoChannelId: t,
44
+ customNotificationHandler: r,
44
45
  children: N,
45
- autoRegister: x = !0
46
+ autoRegister: m = !0
46
47
  }) => {
47
- const [u, v] = h(null), o = D(), [p, K] = h(
48
+ const { registerPushTokenToChannel: h, unregisterPushTokenFromChannel: x } = T(), [s, v] = f(null), n = w(), [p, K] = f(
48
49
  () => () => {
49
50
  }
50
- ), [g, y] = h(() => () => {
51
- }), C = r(
52
- (t) => {
53
- K(() => t);
51
+ ), [g, E] = f(() => () => {
52
+ }), S = a(
53
+ (o) => {
54
+ K(() => o);
54
55
  },
55
56
  []
56
- ), S = r(
57
- (t) => {
58
- y(() => t);
57
+ ), y = a(
58
+ (o) => {
59
+ E(() => o);
59
60
  },
60
61
  []
61
- ), l = r(async () => {
62
+ ), u = a(async () => {
62
63
  try {
63
- o.log("[Knock] Registering for push notifications");
64
- const t = await B();
65
- o.log(`[Knock] Token received: ${t == null ? void 0 : t.data}`), t != null && t.data && (o.log(`[Knock] Setting push token: ${t.data}`), v(t.data));
66
- } catch (t) {
67
- console.error("[Knock] Error registering for push notifications:", t);
64
+ n.log("[Knock] Registering for push notifications");
65
+ const o = await D();
66
+ n.log(`[Knock] Token received: ${o == null ? void 0 : o.data}`), o != null && o.data && (n.log(`[Knock] Setting push token: ${o.data}`), v(o.data));
67
+ } catch (o) {
68
+ console.error("[Knock] Error registering for push notifications:", o);
68
69
  }
69
- }, [o]), k = r(
70
- async (t, i) => {
71
- const e = t.request.content.data.knock_message_id;
72
- return o.messages.updateStatus(e, i);
73
- },
74
- [o]
75
- ), a = r(
76
- async (t, i) => o.user.setChannelData({
77
- channelId: i,
78
- channelData: { tokens: t }
79
- }),
80
- [o]
81
- ), P = r(
82
- async (t, i) => {
83
- o.user.getChannelData({ channelId: i }).then((e) => {
84
- const d = e.data.tokens;
85
- if (!d.includes(t))
86
- return d.push(t), a(d, i);
87
- o.log("[Knock] registerPushTokenToChannel success");
88
- }).catch((e) => a([t], i));
89
- },
90
- [o, a]
91
- ), T = r(
92
- async (t, i) => {
93
- o.user.getChannelData({ channelId: i }).then((e) => {
94
- const E = e.data.tokens.filter(
95
- (w) => w !== t
96
- );
97
- return o.log("unregisterPushTokenFromChannel success"), a(E, i);
98
- }).catch((e) => {
99
- console.error(
100
- "[Knock] Error unregistering push token from channel:",
101
- e
102
- );
103
- });
70
+ }, [n]), k = a(
71
+ async (o, d) => {
72
+ const e = o.request.content.data.knock_message_id;
73
+ return n.messages.updateStatus(e, d);
104
74
  },
105
- [o, a]
75
+ [n]
106
76
  );
107
77
  return H(() => {
108
- s.setNotificationHandler({
109
- handleNotification: c ?? j
110
- }), x && l().then(() => {
111
- u && P(u, n).then((e) => {
112
- o.log("[Knock] setChannelData success");
78
+ i.setNotificationHandler({
79
+ handleNotification: r ?? I
80
+ }), m && u().then(() => {
81
+ s && h(s, t).then((e) => {
82
+ n.log("[Knock] setChannelData success");
113
83
  }).catch((e) => {
114
84
  console.error(
115
85
  "[Knock] Error in setting push token or channel data",
@@ -122,55 +92,55 @@ const I = ({
122
92
  e
123
93
  );
124
94
  });
125
- const t = s.addNotificationReceivedListener((e) => {
126
- o.log(
95
+ const o = i.addNotificationReceivedListener((e) => {
96
+ n.log(
127
97
  "[Knock] Expo Push Notification received in foreground:"
128
98
  ), k(e, "interacted"), p(e);
129
- }), i = s.addNotificationResponseReceivedListener((e) => {
130
- o.log("[Knock] Expo Push Notification was interacted with"), k(
99
+ }), d = i.addNotificationResponseReceivedListener((e) => {
100
+ n.log("[Knock] Expo Push Notification was interacted with"), k(
131
101
  e.notification,
132
102
  "interacted"
133
103
  ), g(e);
134
104
  });
135
105
  return () => {
136
- s.removeNotificationSubscription(
137
- t
138
- ), s.removeNotificationSubscription(
139
- i
106
+ i.removeNotificationSubscription(
107
+ o
108
+ ), i.removeNotificationSubscription(
109
+ d
140
110
  );
141
111
  };
142
112
  }, [
143
- l,
113
+ u,
144
114
  p,
145
115
  g,
146
- c,
147
- u,
148
- n,
149
- o
150
- ]), /* @__PURE__ */ R(
151
- m.Provider,
116
+ r,
117
+ s,
118
+ t,
119
+ n
120
+ ]), /* @__PURE__ */ l(
121
+ P.Provider,
152
122
  {
153
123
  value: {
154
- expoPushToken: u,
155
- registerForPushNotifications: l,
156
- registerPushTokenToChannel: P,
157
- unregisterPushTokenFromChannel: T,
158
- onNotificationReceived: C,
159
- onNotificationTapped: S
124
+ expoPushToken: s,
125
+ registerForPushNotifications: u,
126
+ registerPushTokenToChannel: h,
127
+ unregisterPushTokenFromChannel: x,
128
+ onNotificationReceived: S,
129
+ onNotificationTapped: y
160
130
  },
161
131
  children: N
162
132
  }
163
133
  );
164
- }, O = () => {
165
- const n = _(m);
166
- if (n === void 0)
134
+ }, G = (t) => /* @__PURE__ */ l(C, { children: /* @__PURE__ */ l(_, { ...t }) }), z = () => {
135
+ const t = A(P);
136
+ if (t === void 0)
167
137
  throw new Error(
168
- "[Knock] useExpoPushNotifications must be used within a PushNotificationProvider"
138
+ "[Knock] useExpoPushNotifications must be used within a KnockExpoPushNotificationProvider"
169
139
  );
170
- return n;
140
+ return t;
171
141
  };
172
142
  export {
173
- I as KnockExpoPushNotificationProvider,
174
- O as useExpoPushNotifications
143
+ G as KnockExpoPushNotificationProvider,
144
+ z as useExpoPushNotifications
175
145
  };
176
146
  //# sourceMappingURL=KnockExpoPushNotificationProvider.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"KnockExpoPushNotificationProvider.mjs","sources":["../../../../src/modules/push/KnockExpoPushNotificationProvider.tsx"],"sourcesContent":["import {\n ChannelData,\n Message,\n MessageEngagementStatus,\n} from \"@knocklabs/client\";\nimport { useKnockClient } from \"@knocklabs/react-core\";\nimport Constants from \"expo-constants\";\nimport * as Device from \"expo-device\";\nimport * as Notifications from \"expo-notifications\";\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from \"react\";\n\nexport interface KnockExpoPushNotificationContextType {\n expoPushToken: string | null;\n registerForPushNotifications: () => Promise<void>;\n registerPushTokenToChannel(token: string, channelId: string): Promise<void>;\n unregisterPushTokenFromChannel(\n token: string,\n channelId: string,\n ): Promise<void>;\n onNotificationReceived: (\n handler: (notification: Notifications.Notification) => void,\n ) => void;\n onNotificationTapped: (\n handler: (response: Notifications.NotificationResponse) => void,\n ) => void;\n}\n\nNotifications.setNotificationHandler({\n handleNotification: async () => {\n return {\n shouldShowAlert: true,\n shouldPlaySound: true,\n shouldSetBadge: true,\n };\n },\n});\n\nconst defaultNotificationHandler = async (\n _notification: Notifications.Notification,\n): Promise<Notifications.NotificationBehavior> => {\n return {\n shouldShowAlert: true,\n shouldPlaySound: true,\n shouldSetBadge: true,\n };\n};\n\nconst KnockExpoPushNotificationContext = createContext<\n KnockExpoPushNotificationContextType | undefined\n>(undefined);\n\nexport interface KnockExpoPushNotificationProviderProps {\n knockExpoChannelId: string;\n customNotificationHandler?: (\n notification: Notifications.Notification,\n ) => Promise<Notifications.NotificationBehavior>;\n children?: React.ReactElement;\n autoRegister?: boolean;\n}\n\nasync function requestPushPermissionIfNeeded(): Promise<string> {\n const { status: existingStatus } = await Notifications.getPermissionsAsync();\n\n if (existingStatus !== \"granted\") {\n const { status } = await Notifications.requestPermissionsAsync();\n return status;\n }\n\n return existingStatus;\n}\n\nasync function getExpoPushToken(): Promise<Notifications.ExpoPushToken | null> {\n try {\n if (\n !Constants.expoConfig ||\n !Constants.expoConfig.extra ||\n !Constants.expoConfig.extra.eas\n ) {\n console.error(\n \"[Knock] Expo Project ID is not defined in the app configuration.\",\n );\n return null;\n }\n const token = await Notifications.getExpoPushTokenAsync({\n projectId: Constants.expoConfig.extra.eas.projectId,\n });\n return token;\n } catch (error) {\n console.error(\"[Knock] Error getting Expo push token:\", error);\n return null;\n }\n}\n\nasync function requestPermissionAndGetPushToken(): Promise<Notifications.ExpoPushToken | null> {\n // Check for device support\n if (!Device.isDevice) {\n console.warn(\"[Knock] Must use physical device for Push Notifications\");\n return null;\n }\n\n const permissionStatus = await requestPushPermissionIfNeeded();\n\n if (permissionStatus !== \"granted\") {\n console.warn(\"[Knock] Push notification permission not granted\");\n return null;\n }\n\n return getExpoPushToken();\n}\n\nexport const KnockExpoPushNotificationProvider: React.FC<\n KnockExpoPushNotificationProviderProps\n> = ({\n knockExpoChannelId,\n customNotificationHandler,\n children,\n autoRegister = true,\n}) => {\n const [expoPushToken, setExpoPushToken] = useState<string | null>(null);\n const knockClient = useKnockClient();\n\n const [notificationReceivedHandler, setNotificationReceivedHandler] =\n useState<(notification: Notifications.Notification) => void>(\n () => () => {},\n );\n\n const [notificationTappedHandler, setNotificationTappedHandler] = useState<\n (response: Notifications.NotificationResponse) => void\n >(() => () => {});\n\n const handleNotificationReceived = useCallback(\n (handler: (notification: Notifications.Notification) => void) => {\n setNotificationReceivedHandler(() => handler);\n },\n [],\n );\n\n const handleNotificationTapped = useCallback(\n (handler: (response: Notifications.NotificationResponse) => void) => {\n setNotificationTappedHandler(() => handler);\n },\n [],\n );\n\n const registerForPushNotifications = useCallback(async (): Promise<void> => {\n try {\n knockClient.log(`[Knock] Registering for push notifications`);\n const token = await requestPermissionAndGetPushToken();\n knockClient.log(`[Knock] Token received: ${token?.data}`);\n if (token?.data) {\n knockClient.log(`[Knock] Setting push token: ${token.data}`);\n setExpoPushToken(token.data);\n }\n } catch (error) {\n console.error(`[Knock] Error registering for push notifications:`, error);\n }\n }, [knockClient]);\n\n const updateKnockMessageStatusFromNotification = useCallback(\n async (\n notification: Notifications.Notification,\n status: MessageEngagementStatus,\n ): Promise<Message> => {\n const messageId = notification.request.content.data[\"knock_message_id\"];\n return knockClient.messages.updateStatus(messageId, status);\n },\n [knockClient],\n );\n\n const registerNewTokenDataOnServer = useCallback(\n async (tokens: string[], channelId: string): Promise<ChannelData> => {\n return knockClient.user.setChannelData({\n channelId: channelId,\n channelData: { tokens: tokens },\n });\n },\n [knockClient],\n );\n\n const registerPushTokenToChannel = useCallback(\n async (token: string, channelId: string): Promise<void> => {\n knockClient.user\n .getChannelData({ channelId: channelId })\n .then((result: ChannelData) => {\n const tokens: string[] = result.data[\"tokens\"];\n if (!tokens.includes(token)) {\n tokens.push(token);\n return registerNewTokenDataOnServer(tokens, channelId);\n }\n knockClient.log(\"[Knock] registerPushTokenToChannel success\");\n })\n .catch((_) => {\n // No data registered on that channel for that user, we'll create a new record\n return registerNewTokenDataOnServer([token], channelId);\n });\n },\n [knockClient, registerNewTokenDataOnServer],\n );\n\n const unregisterPushTokenFromChannel = useCallback(\n async (token: string, channelId: string): Promise<void> => {\n knockClient.user\n .getChannelData({ channelId: channelId })\n .then((result: ChannelData) => {\n const tokens: string[] = result.data[\"tokens\"];\n const updatedTokens = tokens.filter(\n (channelToken) => channelToken !== token,\n );\n knockClient.log(\"unregisterPushTokenFromChannel success\");\n return registerNewTokenDataOnServer(updatedTokens, channelId);\n })\n .catch((error) => {\n console.error(\n `[Knock] Error unregistering push token from channel:`,\n error,\n );\n });\n },\n [knockClient, registerNewTokenDataOnServer],\n );\n\n useEffect(() => {\n Notifications.setNotificationHandler({\n handleNotification:\n customNotificationHandler ?? defaultNotificationHandler,\n });\n\n if (autoRegister) {\n registerForPushNotifications()\n .then(() => {\n if (expoPushToken) {\n registerPushTokenToChannel(expoPushToken, knockExpoChannelId)\n .then((_result) => {\n knockClient.log(\"[Knock] setChannelData success\");\n })\n .catch((_error) => {\n console.error(\n \"[Knock] Error in setting push token or channel data\",\n _error,\n );\n });\n }\n })\n .catch((_error) => {\n console.error(\n \"[Knock] Error in setting push token or channel data\",\n _error,\n );\n });\n }\n\n const notificationReceivedSubscription =\n Notifications.addNotificationReceivedListener((notification) => {\n knockClient.log(\n \"[Knock] Expo Push Notification received in foreground:\",\n );\n updateKnockMessageStatusFromNotification(notification, \"interacted\");\n notificationReceivedHandler(notification);\n });\n\n const notificationResponseSubscription =\n Notifications.addNotificationResponseReceivedListener((response) => {\n knockClient.log(\"[Knock] Expo Push Notification was interacted with\");\n updateKnockMessageStatusFromNotification(\n response.notification,\n \"interacted\",\n );\n notificationTappedHandler(response);\n });\n\n return () => {\n Notifications.removeNotificationSubscription(\n notificationReceivedSubscription,\n );\n Notifications.removeNotificationSubscription(\n notificationResponseSubscription,\n );\n };\n\n // TODO: Remove when possible and ensure dependency array is correct\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n registerForPushNotifications,\n notificationReceivedHandler,\n notificationTappedHandler,\n customNotificationHandler,\n expoPushToken,\n knockExpoChannelId,\n knockClient,\n ]);\n\n return (\n <KnockExpoPushNotificationContext.Provider\n value={{\n expoPushToken,\n registerForPushNotifications,\n registerPushTokenToChannel,\n unregisterPushTokenFromChannel,\n onNotificationReceived: handleNotificationReceived,\n onNotificationTapped: handleNotificationTapped,\n }}\n >\n {children}\n </KnockExpoPushNotificationContext.Provider>\n );\n};\n\nexport const useExpoPushNotifications =\n (): KnockExpoPushNotificationContextType => {\n const context = useContext(KnockExpoPushNotificationContext);\n if (context === undefined) {\n throw new Error(\n \"[Knock] useExpoPushNotifications must be used within a PushNotificationProvider\",\n );\n }\n return context;\n };\n"],"names":["Notifications","defaultNotificationHandler","_notification","KnockExpoPushNotificationContext","createContext","requestPushPermissionIfNeeded","existingStatus","status","getExpoPushToken","Constants","error","requestPermissionAndGetPushToken","Device","KnockExpoPushNotificationProvider","knockExpoChannelId","customNotificationHandler","children","autoRegister","expoPushToken","setExpoPushToken","useState","knockClient","useKnockClient","notificationReceivedHandler","setNotificationReceivedHandler","notificationTappedHandler","setNotificationTappedHandler","handleNotificationReceived","useCallback","handler","handleNotificationTapped","registerForPushNotifications","token","updateKnockMessageStatusFromNotification","notification","messageId","registerNewTokenDataOnServer","tokens","channelId","registerPushTokenToChannel","result","_","unregisterPushTokenFromChannel","updatedTokens","channelToken","useEffect","_result","_error","notificationReceivedSubscription","notificationResponseSubscription","response","jsx","useExpoPushNotifications","context","useContext"],"mappings":"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"}
1
+ {"version":3,"file":"KnockExpoPushNotificationProvider.mjs","sources":["../../../../src/modules/push/KnockExpoPushNotificationProvider.tsx"],"sourcesContent":["import { Message, MessageEngagementStatus } from \"@knocklabs/client\";\nimport { useKnockClient } from \"@knocklabs/react-core\";\nimport {\n type KnockPushNotificationContextType,\n KnockPushNotificationProvider,\n usePushNotifications,\n} from \"@knocklabs/react-native\";\nimport Constants from \"expo-constants\";\nimport * as Device from \"expo-device\";\nimport * as Notifications from \"expo-notifications\";\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from \"react\";\n\nexport interface KnockExpoPushNotificationContextType\n extends KnockPushNotificationContextType {\n expoPushToken: string | null;\n registerForPushNotifications: () => Promise<void>;\n onNotificationReceived: (\n handler: (notification: Notifications.Notification) => void,\n ) => void;\n onNotificationTapped: (\n handler: (response: Notifications.NotificationResponse) => void,\n ) => void;\n}\n\nNotifications.setNotificationHandler({\n handleNotification: async () => {\n return {\n shouldShowAlert: true,\n shouldPlaySound: true,\n shouldSetBadge: true,\n };\n },\n});\n\nconst defaultNotificationHandler = async (\n _notification: Notifications.Notification,\n): Promise<Notifications.NotificationBehavior> => {\n return {\n shouldShowAlert: true,\n shouldPlaySound: true,\n shouldSetBadge: true,\n };\n};\n\nconst KnockExpoPushNotificationContext = createContext<\n KnockExpoPushNotificationContextType | undefined\n>(undefined);\n\nexport interface KnockExpoPushNotificationProviderProps {\n knockExpoChannelId: string;\n customNotificationHandler?: (\n notification: Notifications.Notification,\n ) => Promise<Notifications.NotificationBehavior>;\n children?: React.ReactElement;\n autoRegister?: boolean;\n}\n\nasync function requestPushPermissionIfNeeded(): Promise<string> {\n const { status: existingStatus } = await Notifications.getPermissionsAsync();\n\n if (existingStatus !== \"granted\") {\n const { status } = await Notifications.requestPermissionsAsync();\n return status;\n }\n\n return existingStatus;\n}\n\nasync function getExpoPushToken(): Promise<Notifications.ExpoPushToken | null> {\n try {\n if (\n !Constants.expoConfig ||\n !Constants.expoConfig.extra ||\n !Constants.expoConfig.extra.eas\n ) {\n console.error(\n \"[Knock] Expo Project ID is not defined in the app configuration.\",\n );\n return null;\n }\n const token = await Notifications.getExpoPushTokenAsync({\n projectId: Constants.expoConfig.extra.eas.projectId,\n });\n return token;\n } catch (error) {\n console.error(\"[Knock] Error getting Expo push token:\", error);\n return null;\n }\n}\n\nasync function requestPermissionAndGetPushToken(): Promise<Notifications.ExpoPushToken | null> {\n // Check for device support\n if (!Device.isDevice) {\n console.warn(\"[Knock] Must use physical device for Push Notifications\");\n return null;\n }\n\n const permissionStatus = await requestPushPermissionIfNeeded();\n\n if (permissionStatus !== \"granted\") {\n console.warn(\"[Knock] Push notification permission not granted\");\n return null;\n }\n\n return getExpoPushToken();\n}\n\nconst InternalKnockExpoPushNotificationProvider: React.FC<\n KnockExpoPushNotificationProviderProps\n> = ({\n knockExpoChannelId,\n customNotificationHandler,\n children,\n autoRegister = true,\n}) => {\n const { registerPushTokenToChannel, unregisterPushTokenFromChannel } =\n usePushNotifications();\n const [expoPushToken, setExpoPushToken] = useState<string | null>(null);\n const knockClient = useKnockClient();\n\n const [notificationReceivedHandler, setNotificationReceivedHandler] =\n useState<(notification: Notifications.Notification) => void>(\n () => () => {},\n );\n\n const [notificationTappedHandler, setNotificationTappedHandler] = useState<\n (response: Notifications.NotificationResponse) => void\n >(() => () => {});\n\n const handleNotificationReceived = useCallback(\n (handler: (notification: Notifications.Notification) => void) => {\n setNotificationReceivedHandler(() => handler);\n },\n [],\n );\n\n const handleNotificationTapped = useCallback(\n (handler: (response: Notifications.NotificationResponse) => void) => {\n setNotificationTappedHandler(() => handler);\n },\n [],\n );\n\n const registerForPushNotifications = useCallback(async (): Promise<void> => {\n try {\n knockClient.log(`[Knock] Registering for push notifications`);\n const token = await requestPermissionAndGetPushToken();\n knockClient.log(`[Knock] Token received: ${token?.data}`);\n if (token?.data) {\n knockClient.log(`[Knock] Setting push token: ${token.data}`);\n setExpoPushToken(token.data);\n }\n } catch (error) {\n console.error(`[Knock] Error registering for push notifications:`, error);\n }\n }, [knockClient]);\n\n const updateKnockMessageStatusFromNotification = useCallback(\n async (\n notification: Notifications.Notification,\n status: MessageEngagementStatus,\n ): Promise<Message> => {\n const messageId = notification.request.content.data[\"knock_message_id\"];\n return knockClient.messages.updateStatus(messageId, status);\n },\n [knockClient],\n );\n\n useEffect(() => {\n Notifications.setNotificationHandler({\n handleNotification:\n customNotificationHandler ?? defaultNotificationHandler,\n });\n\n if (autoRegister) {\n registerForPushNotifications()\n .then(() => {\n if (expoPushToken) {\n registerPushTokenToChannel(expoPushToken, knockExpoChannelId)\n .then((_result) => {\n knockClient.log(\"[Knock] setChannelData success\");\n })\n .catch((_error) => {\n console.error(\n \"[Knock] Error in setting push token or channel data\",\n _error,\n );\n });\n }\n })\n .catch((_error) => {\n console.error(\n \"[Knock] Error in setting push token or channel data\",\n _error,\n );\n });\n }\n\n const notificationReceivedSubscription =\n Notifications.addNotificationReceivedListener((notification) => {\n knockClient.log(\n \"[Knock] Expo Push Notification received in foreground:\",\n );\n updateKnockMessageStatusFromNotification(notification, \"interacted\");\n notificationReceivedHandler(notification);\n });\n\n const notificationResponseSubscription =\n Notifications.addNotificationResponseReceivedListener((response) => {\n knockClient.log(\"[Knock] Expo Push Notification was interacted with\");\n updateKnockMessageStatusFromNotification(\n response.notification,\n \"interacted\",\n );\n notificationTappedHandler(response);\n });\n\n return () => {\n Notifications.removeNotificationSubscription(\n notificationReceivedSubscription,\n );\n Notifications.removeNotificationSubscription(\n notificationResponseSubscription,\n );\n };\n\n // TODO: Remove when possible and ensure dependency array is correct\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n registerForPushNotifications,\n notificationReceivedHandler,\n notificationTappedHandler,\n customNotificationHandler,\n expoPushToken,\n knockExpoChannelId,\n knockClient,\n ]);\n\n return (\n <KnockExpoPushNotificationContext.Provider\n value={{\n expoPushToken,\n registerForPushNotifications,\n registerPushTokenToChannel,\n unregisterPushTokenFromChannel,\n onNotificationReceived: handleNotificationReceived,\n onNotificationTapped: handleNotificationTapped,\n }}\n >\n {children}\n </KnockExpoPushNotificationContext.Provider>\n );\n};\n\nexport const KnockExpoPushNotificationProvider: React.FC<\n KnockExpoPushNotificationProviderProps\n> = (props) => {\n return (\n <KnockPushNotificationProvider>\n <InternalKnockExpoPushNotificationProvider {...props} />\n </KnockPushNotificationProvider>\n );\n};\n\nexport const useExpoPushNotifications =\n (): KnockExpoPushNotificationContextType => {\n const context = useContext(KnockExpoPushNotificationContext);\n if (context === undefined) {\n throw new Error(\n \"[Knock] useExpoPushNotifications must be used within a KnockExpoPushNotificationProvider\",\n );\n }\n return context;\n };\n"],"names":["Notifications","defaultNotificationHandler","_notification","KnockExpoPushNotificationContext","createContext","requestPushPermissionIfNeeded","existingStatus","status","getExpoPushToken","Constants","error","requestPermissionAndGetPushToken","Device","InternalKnockExpoPushNotificationProvider","knockExpoChannelId","customNotificationHandler","children","autoRegister","registerPushTokenToChannel","unregisterPushTokenFromChannel","usePushNotifications","expoPushToken","setExpoPushToken","useState","knockClient","useKnockClient","notificationReceivedHandler","setNotificationReceivedHandler","notificationTappedHandler","setNotificationTappedHandler","handleNotificationReceived","useCallback","handler","handleNotificationTapped","registerForPushNotifications","token","updateKnockMessageStatusFromNotification","notification","messageId","useEffect","_result","_error","notificationReceivedSubscription","notificationResponseSubscription","response","jsx","KnockExpoPushNotificationProvider","props","KnockPushNotificationProvider","useExpoPushNotifications","context","useContext"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
+ import { KnockPushNotificationContextType } from '@knocklabs/react-native';
1
2
  import { default as React } from 'react';
3
+
2
4
  import * as Notifications from "expo-notifications";
3
- export interface KnockExpoPushNotificationContextType {
5
+ export interface KnockExpoPushNotificationContextType extends KnockPushNotificationContextType {
4
6
  expoPushToken: string | null;
5
7
  registerForPushNotifications: () => Promise<void>;
6
- registerPushTokenToChannel(token: string, channelId: string): Promise<void>;
7
- unregisterPushTokenFromChannel(token: string, channelId: string): Promise<void>;
8
8
  onNotificationReceived: (handler: (notification: Notifications.Notification) => void) => void;
9
9
  onNotificationTapped: (handler: (response: Notifications.NotificationResponse) => void) => void;
10
10
  }
@@ -1 +1 @@
1
- {"version":3,"file":"KnockExpoPushNotificationProvider.d.ts","sourceRoot":"","sources":["../../../../src/modules/push/KnockExpoPushNotificationProvider.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAMN,MAAM,OAAO,CAAC;AAEf,MAAM,WAAW,oCAAoC;IACnD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,4BAA4B,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,8BAA8B,CAC5B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,sBAAsB,EAAE,CACtB,OAAO,EAAE,CAAC,YAAY,EAAE,aAAa,CAAC,YAAY,KAAK,IAAI,KACxD,IAAI,CAAC;IACV,oBAAoB,EAAE,CACpB,OAAO,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,oBAAoB,KAAK,IAAI,KAC5D,IAAI,CAAC;CACX;AA0BD,MAAM,WAAW,sCAAsC;IACrD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yBAAyB,CAAC,EAAE,CAC1B,YAAY,EAAE,aAAa,CAAC,YAAY,KACrC,OAAO,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAC;IACjD,QAAQ,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC;IAC9B,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAoDD,eAAO,MAAM,iCAAiC,EAAE,KAAK,CAAC,EAAE,CACtD,sCAAsC,CAkMvC,CAAC;AAEF,eAAO,MAAM,wBAAwB,QAC/B,oCAQH,CAAC"}
1
+ {"version":3,"file":"KnockExpoPushNotificationProvider.d.ts","sourceRoot":"","sources":["../../../../src/modules/push/KnockExpoPushNotificationProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,gCAAgC,EAGtC,MAAM,yBAAyB,CAAC;AAGjC,OAAO,KAAK,aAAa,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAMN,MAAM,OAAO,CAAC;AAEf,MAAM,WAAW,oCACf,SAAQ,gCAAgC;IACxC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,4BAA4B,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,sBAAsB,EAAE,CACtB,OAAO,EAAE,CAAC,YAAY,EAAE,aAAa,CAAC,YAAY,KAAK,IAAI,KACxD,IAAI,CAAC;IACV,oBAAoB,EAAE,CACpB,OAAO,EAAE,CAAC,QAAQ,EAAE,aAAa,CAAC,oBAAoB,KAAK,IAAI,KAC5D,IAAI,CAAC;CACX;AA0BD,MAAM,WAAW,sCAAsC;IACrD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yBAAyB,CAAC,EAAE,CAC1B,YAAY,EAAE,aAAa,CAAC,YAAY,KACrC,OAAO,CAAC,aAAa,CAAC,oBAAoB,CAAC,CAAC;IACjD,QAAQ,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC;IAC9B,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAuMD,eAAO,MAAM,iCAAiC,EAAE,KAAK,CAAC,EAAE,CACtD,sCAAsC,CAOvC,CAAC;AAEF,eAAO,MAAM,wBAAwB,QAC/B,oCAQH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knocklabs/expo",
3
- "version": "0.1.0",
3
+ "version": "0.2.1-rc.0",
4
4
  "author": "@knocklabs",
5
5
  "license": "MIT",
6
6
  "main": "dist/cjs/index.js",
@@ -49,9 +49,9 @@
49
49
  "react-native": "*"
50
50
  },
51
51
  "dependencies": {
52
- "@knocklabs/client": "^0.10.13",
53
- "@knocklabs/react-core": "^0.2.25",
54
- "@knocklabs/react-native": "^0.4.0",
52
+ "@knocklabs/client": "^0.11.0-rc.0",
53
+ "@knocklabs/react-core": "^0.3.0-rc.0",
54
+ "@knocklabs/react-native": "^0.5.1-rc.0",
55
55
  "react-native-gesture-handler": "^2.19.0",
56
56
  "react-native-render-html": "^6.3.4",
57
57
  "react-native-svg": "^15.6.0"
@@ -1,9 +1,10 @@
1
- import {
2
- ChannelData,
3
- Message,
4
- MessageEngagementStatus,
5
- } from "@knocklabs/client";
1
+ import { Message, MessageEngagementStatus } from "@knocklabs/client";
6
2
  import { useKnockClient } from "@knocklabs/react-core";
3
+ import {
4
+ type KnockPushNotificationContextType,
5
+ KnockPushNotificationProvider,
6
+ usePushNotifications,
7
+ } from "@knocklabs/react-native";
7
8
  import Constants from "expo-constants";
8
9
  import * as Device from "expo-device";
9
10
  import * as Notifications from "expo-notifications";
@@ -15,14 +16,10 @@ import React, {
15
16
  useState,
16
17
  } from "react";
17
18
 
18
- export interface KnockExpoPushNotificationContextType {
19
+ export interface KnockExpoPushNotificationContextType
20
+ extends KnockPushNotificationContextType {
19
21
  expoPushToken: string | null;
20
22
  registerForPushNotifications: () => Promise<void>;
21
- registerPushTokenToChannel(token: string, channelId: string): Promise<void>;
22
- unregisterPushTokenFromChannel(
23
- token: string,
24
- channelId: string,
25
- ): Promise<void>;
26
23
  onNotificationReceived: (
27
24
  handler: (notification: Notifications.Notification) => void,
28
25
  ) => void;
@@ -114,7 +111,7 @@ async function requestPermissionAndGetPushToken(): Promise<Notifications.ExpoPus
114
111
  return getExpoPushToken();
115
112
  }
116
113
 
117
- export const KnockExpoPushNotificationProvider: React.FC<
114
+ const InternalKnockExpoPushNotificationProvider: React.FC<
118
115
  KnockExpoPushNotificationProviderProps
119
116
  > = ({
120
117
  knockExpoChannelId,
@@ -122,6 +119,8 @@ export const KnockExpoPushNotificationProvider: React.FC<
122
119
  children,
123
120
  autoRegister = true,
124
121
  }) => {
122
+ const { registerPushTokenToChannel, unregisterPushTokenFromChannel } =
123
+ usePushNotifications();
125
124
  const [expoPushToken, setExpoPushToken] = useState<string | null>(null);
126
125
  const knockClient = useKnockClient();
127
126
 
@@ -173,58 +172,6 @@ export const KnockExpoPushNotificationProvider: React.FC<
173
172
  [knockClient],
174
173
  );
175
174
 
176
- const registerNewTokenDataOnServer = useCallback(
177
- async (tokens: string[], channelId: string): Promise<ChannelData> => {
178
- return knockClient.user.setChannelData({
179
- channelId: channelId,
180
- channelData: { tokens: tokens },
181
- });
182
- },
183
- [knockClient],
184
- );
185
-
186
- const registerPushTokenToChannel = useCallback(
187
- async (token: string, channelId: string): Promise<void> => {
188
- knockClient.user
189
- .getChannelData({ channelId: channelId })
190
- .then((result: ChannelData) => {
191
- const tokens: string[] = result.data["tokens"];
192
- if (!tokens.includes(token)) {
193
- tokens.push(token);
194
- return registerNewTokenDataOnServer(tokens, channelId);
195
- }
196
- knockClient.log("[Knock] registerPushTokenToChannel success");
197
- })
198
- .catch((_) => {
199
- // No data registered on that channel for that user, we'll create a new record
200
- return registerNewTokenDataOnServer([token], channelId);
201
- });
202
- },
203
- [knockClient, registerNewTokenDataOnServer],
204
- );
205
-
206
- const unregisterPushTokenFromChannel = useCallback(
207
- async (token: string, channelId: string): Promise<void> => {
208
- knockClient.user
209
- .getChannelData({ channelId: channelId })
210
- .then((result: ChannelData) => {
211
- const tokens: string[] = result.data["tokens"];
212
- const updatedTokens = tokens.filter(
213
- (channelToken) => channelToken !== token,
214
- );
215
- knockClient.log("unregisterPushTokenFromChannel success");
216
- return registerNewTokenDataOnServer(updatedTokens, channelId);
217
- })
218
- .catch((error) => {
219
- console.error(
220
- `[Knock] Error unregistering push token from channel:`,
221
- error,
222
- );
223
- });
224
- },
225
- [knockClient, registerNewTokenDataOnServer],
226
- );
227
-
228
175
  useEffect(() => {
229
176
  Notifications.setNotificationHandler({
230
177
  handleNotification:
@@ -311,12 +258,22 @@ export const KnockExpoPushNotificationProvider: React.FC<
311
258
  );
312
259
  };
313
260
 
261
+ export const KnockExpoPushNotificationProvider: React.FC<
262
+ KnockExpoPushNotificationProviderProps
263
+ > = (props) => {
264
+ return (
265
+ <KnockPushNotificationProvider>
266
+ <InternalKnockExpoPushNotificationProvider {...props} />
267
+ </KnockPushNotificationProvider>
268
+ );
269
+ };
270
+
314
271
  export const useExpoPushNotifications =
315
272
  (): KnockExpoPushNotificationContextType => {
316
273
  const context = useContext(KnockExpoPushNotificationContext);
317
274
  if (context === undefined) {
318
275
  throw new Error(
319
- "[Knock] useExpoPushNotifications must be used within a PushNotificationProvider",
276
+ "[Knock] useExpoPushNotifications must be used within a KnockExpoPushNotificationProvider",
320
277
  );
321
278
  }
322
279
  return context;