@knocklabs/expo 0.3.49 → 0.3.50

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,11 @@
1
1
  # @knocklabs/expo
2
2
 
3
+ ## 0.3.50
4
+
5
+ ### Patch Changes
6
+
7
+ - d48e3b6: fix: update KnockExpoPushNotificationProvider to use updated unsubscribe method
8
+
3
9
  ## 0.3.49
4
10
 
5
11
  ### Patch Changes
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("react/jsx-runtime"),w=require("@knocklabs/react-core"),x=require("@knocklabs/react-native"),T=require("expo-constants"),j=require("expo-device"),_=require("expo-notifications"),i=require("react"),q=t=>t&&typeof t=="object"&&"default"in t?t:{default:t};function S(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=q(T),R=S(j),s=S(_);s.setNotificationHandler({handleNotification:async()=>({shouldShowAlert:!0,shouldPlaySound:!0,shouldSetBadge:!0,shouldShowBanner:!0,shouldShowList:!0})});const D=async t=>({shouldShowAlert:!0,shouldPlaySound:!0,shouldSetBadge:!0,shouldShowBanner:!0,shouldShowList:!0}),v=i.createContext(void 0);async function A(){const{status:t}=await s.getPermissionsAsync();if(t!=="granted"){const{status:r}=await s.requestPermissionsAsync();return r}return t}async function H(){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 O(){return R.isDevice?await A()!=="granted"?(console.warn("[Knock] Push notification permission not granted"),null):H():(console.warn("[Knock] Must use physical device for Push Notifications"),null)}const I=({knockExpoChannelId:t,customNotificationHandler:r,children:c,autoRegister:a=!0})=>{const{registerPushTokenToChannel:p,unregisterPushTokenFromChannel:K}=x.usePushNotifications(),[u,m]=i.useState(null),n=w.useKnockClient(),[g,y]=i.useState(()=>()=>{}),[k,C]=i.useState(()=>()=>{}),E=i.useCallback(e=>{y(()=>e)},[]),b=i.useCallback(e=>{C(()=>e)},[]),f=i.useCallback(async()=>{try{n.log("[Knock] Registering for push notifications");const e=await O();n.log(`[Knock] Token received: ${e==null?void 0:e.data}`),e!=null&&e.data&&(n.log(`[Knock] Setting push token: ${e.data}`),m(e.data))}catch(e){console.error("[Knock] Error registering for push notifications:",e)}},[n]),P=i.useCallback(async(e,l)=>{var N;const o=(N=e.request.content.data)==null?void 0:N.knock_message_id;if(!o){n.log("[Knock] Skipping status update for non-Knock notification");return}return n.messages.updateStatus(o,l)},[n]);return i.useEffect(()=>{s.setNotificationHandler({handleNotification:r??D}),a&&f().then(()=>{u&&p(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,a,u,t,n]),h.jsx(v.Provider,{value:{expoPushToken:u,registerForPushNotifications:f,registerPushTokenToChannel:p,unregisterPushTokenFromChannel:K,onNotificationReceived:E,onNotificationTapped:b},children:c})},B=t=>h.jsx(x.KnockPushNotificationProvider,{children:h.jsx(I,{...t})}),L=()=>{const t=i.useContext(v);if(t===void 0)throw new Error("[Knock] useExpoPushNotifications must be used within a KnockExpoPushNotificationProvider");return t};exports.KnockExpoPushNotificationProvider=B;exports.useExpoPushNotifications=L;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("react/jsx-runtime"),b=require("@knocklabs/react-core"),x=require("@knocklabs/react-native"),T=require("expo-constants"),j=require("expo-device"),_=require("expo-notifications"),i=require("react"),q=t=>t&&typeof t=="object"&&"default"in t?t:{default:t};function v(t){if(t&&typeof t=="object"&&"default"in t)return t;const s=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(s,c,a.get?a:{enumerable:!0,get:()=>t[c]})}}return s.default=t,Object.freeze(s)}const d=q(T),R=v(j),r=v(_);r.setNotificationHandler({handleNotification:async()=>({shouldShowAlert:!0,shouldPlaySound:!0,shouldSetBadge:!0,shouldShowBanner:!0,shouldShowList:!0})});const D=async t=>({shouldShowAlert:!0,shouldPlaySound:!0,shouldSetBadge:!0,shouldShowBanner:!0,shouldShowList:!0}),S=i.createContext(void 0);async function A(){const{status:t}=await r.getPermissionsAsync();if(t!=="granted"){const{status:s}=await r.requestPermissionsAsync();return s}return t}async function H(){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 r.getExpoPushTokenAsync({projectId:d.default.expoConfig.extra.eas.projectId})}catch(t){return console.error("[Knock] Error getting Expo push token:",t),null}}async function O(){return R.isDevice?await A()!=="granted"?(console.warn("[Knock] Push notification permission not granted"),null):H():(console.warn("[Knock] Must use physical device for Push Notifications"),null)}const I=({knockExpoChannelId:t,customNotificationHandler:s,children:c,autoRegister:a=!0})=>{const{registerPushTokenToChannel:p,unregisterPushTokenFromChannel:K}=x.usePushNotifications(),[u,m]=i.useState(null),n=b.useKnockClient(),[g,y]=i.useState(()=>()=>{}),[k,C]=i.useState(()=>()=>{}),E=i.useCallback(e=>{y(()=>e)},[]),w=i.useCallback(e=>{C(()=>e)},[]),l=i.useCallback(async()=>{try{n.log("[Knock] Registering for push notifications");const e=await O();n.log(`[Knock] Token received: ${e==null?void 0:e.data}`),e!=null&&e.data&&(n.log(`[Knock] Setting push token: ${e.data}`),m(e.data))}catch(e){console.error("[Knock] Error registering for push notifications:",e)}},[n]),P=i.useCallback(async(e,f)=>{var N;const o=(N=e.request.content.data)==null?void 0:N.knock_message_id;if(!o){n.log("[Knock] Skipping status update for non-Knock notification");return}return n.messages.updateStatus(o,f)},[n]);return i.useEffect(()=>{r.setNotificationHandler({handleNotification:s??D}),a&&l().then(()=>{u&&p(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=r.addNotificationReceivedListener(o=>{n.log("[Knock] Expo Push Notification received in foreground:"),P(o,"interacted"),g(o)}),f=r.addNotificationResponseReceivedListener(o=>{n.log("[Knock] Expo Push Notification was interacted with"),P(o.notification,"interacted"),k(o)});return()=>{e.remove(),f.remove()}},[l,g,k,s,a,u,t,n]),h.jsx(S.Provider,{value:{expoPushToken:u,registerForPushNotifications:l,registerPushTokenToChannel:p,unregisterPushTokenFromChannel:K,onNotificationReceived:E,onNotificationTapped:w},children:c})},B=t=>h.jsx(x.KnockPushNotificationProvider,{children:h.jsx(I,{...t})}),L=()=>{const t=i.useContext(S);if(t===void 0)throw new Error("[Knock] useExpoPushNotifications must be used within a KnockExpoPushNotificationProvider");return t};exports.KnockExpoPushNotificationProvider=B;exports.useExpoPushNotifications=L;
2
2
  //# sourceMappingURL=KnockExpoPushNotificationProvider.js.map
@@ -1 +1 @@
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 shouldShowBanner: true,\n shouldShowList: 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 shouldShowBanner: true,\n shouldShowList: 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 | void> => {\n const messageId = notification.request.content.data?.[\n \"knock_message_id\"\n ] as string | undefined;\n\n // Skip status update if this isn't a Knock notification\n // Fixes issue: https://github.com/knocklabs/javascript/issues/589\n if (!messageId) {\n knockClient.log(\n \"[Knock] Skipping status update for non-Knock notification\",\n );\n return;\n }\n\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 autoRegister,\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","_a","useEffect","_result","_error","notificationReceivedSubscription","notificationResponseSubscription","response","jsx","KnockExpoPushNotificationProvider","props","KnockPushNotificationProvider","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 shouldShowBanner: true,\n shouldShowList: 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 shouldShowBanner: true,\n shouldShowList: 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 | void> => {\n const messageId = notification.request.content.data?.[\n \"knock_message_id\"\n ] as string | undefined;\n\n // Skip status update if this isn't a Knock notification\n // Fixes issue: https://github.com/knocklabs/javascript/issues/589\n if (!messageId) {\n knockClient.log(\n \"[Knock] Skipping status update for non-Knock notification\",\n );\n return;\n }\n\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 notificationReceivedSubscription.remove();\n notificationResponseSubscription.remove();\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 autoRegister,\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","_a","useEffect","_result","_error","notificationReceivedSubscription","notificationResponseSubscription","response","jsx","KnockExpoPushNotificationProvider","props","KnockPushNotificationProvider","useExpoPushNotifications","context","useContext"],"mappings":"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"}
@@ -2,9 +2,9 @@ import { jsx as h } from "react/jsx-runtime";
2
2
  import { useKnockClient as C } from "@knocklabs/react-core";
3
3
  import { KnockPushNotificationProvider as T, usePushNotifications as R } from "@knocklabs/react-native";
4
4
  import c from "expo-constants";
5
- import * as b from "expo-device";
5
+ import * as A from "expo-device";
6
6
  import * as i from "expo-notifications";
7
- import { createContext as A, useContext as H, useState as f, useCallback as a, useEffect as I } from "react";
7
+ import { createContext as H, useContext as I, useState as f, useCallback as a, useEffect as b } from "react";
8
8
  i.setNotificationHandler({
9
9
  handleNotification: async () => ({
10
10
  shouldShowAlert: !0,
@@ -20,7 +20,7 @@ const j = async (t) => ({
20
20
  shouldSetBadge: !0,
21
21
  shouldShowBanner: !0,
22
22
  shouldShowList: !0
23
- }), m = A(void 0);
23
+ }), x = H(void 0);
24
24
  async function q() {
25
25
  const { status: t } = await i.getPermissionsAsync();
26
26
  if (t !== "granted") {
@@ -41,15 +41,15 @@ async function B() {
41
41
  }
42
42
  }
43
43
  async function D() {
44
- return b.isDevice ? await q() !== "granted" ? (console.warn("[Knock] Push notification permission not granted"), null) : B() : (console.warn("[Knock] Must use physical device for Push Notifications"), null);
44
+ return A.isDevice ? await q() !== "granted" ? (console.warn("[Knock] Push notification permission not granted"), null) : B() : (console.warn("[Knock] Must use physical device for Push Notifications"), null);
45
45
  }
46
46
  const L = ({
47
47
  knockExpoChannelId: t,
48
48
  customNotificationHandler: r,
49
- children: x,
49
+ children: N,
50
50
  autoRegister: l = !0
51
51
  }) => {
52
- const { registerPushTokenToChannel: p, unregisterPushTokenFromChannel: K } = R(), [s, v] = f(null), e = C(), [g, S] = f(
52
+ const { registerPushTokenToChannel: p, unregisterPushTokenFromChannel: K } = R(), [s, v] = f(null), n = C(), [g, S] = f(
53
53
  () => () => {
54
54
  }
55
55
  ), [k, w] = f(() => () => {
@@ -65,60 +65,56 @@ const L = ({
65
65
  []
66
66
  ), u = a(async () => {
67
67
  try {
68
- e.log("[Knock] Registering for push notifications");
68
+ n.log("[Knock] Registering for push notifications");
69
69
  const o = await D();
70
- e.log(`[Knock] Token received: ${o == null ? void 0 : o.data}`), o != null && o.data && (e.log(`[Knock] Setting push token: ${o.data}`), v(o.data));
70
+ 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));
71
71
  } catch (o) {
72
72
  console.error("[Knock] Error registering for push notifications:", o);
73
73
  }
74
- }, [e]), P = a(
74
+ }, [n]), P = a(
75
75
  async (o, d) => {
76
- var N;
77
- const n = (N = o.request.content.data) == null ? void 0 : N.knock_message_id;
78
- if (!n) {
79
- e.log(
76
+ var m;
77
+ const e = (m = o.request.content.data) == null ? void 0 : m.knock_message_id;
78
+ if (!e) {
79
+ n.log(
80
80
  "[Knock] Skipping status update for non-Knock notification"
81
81
  );
82
82
  return;
83
83
  }
84
- return e.messages.updateStatus(n, d);
84
+ return n.messages.updateStatus(e, d);
85
85
  },
86
- [e]
86
+ [n]
87
87
  );
88
- return I(() => {
88
+ return b(() => {
89
89
  i.setNotificationHandler({
90
90
  handleNotification: r ?? j
91
91
  }), l && u().then(() => {
92
- s && p(s, t).then((n) => {
93
- e.log("[Knock] setChannelData success");
94
- }).catch((n) => {
92
+ s && p(s, t).then((e) => {
93
+ n.log("[Knock] setChannelData success");
94
+ }).catch((e) => {
95
95
  console.error(
96
96
  "[Knock] Error in setting push token or channel data",
97
- n
97
+ e
98
98
  );
99
99
  });
100
- }).catch((n) => {
100
+ }).catch((e) => {
101
101
  console.error(
102
102
  "[Knock] Error in setting push token or channel data",
103
- n
103
+ e
104
104
  );
105
105
  });
106
- const o = i.addNotificationReceivedListener((n) => {
107
- e.log(
106
+ const o = i.addNotificationReceivedListener((e) => {
107
+ n.log(
108
108
  "[Knock] Expo Push Notification received in foreground:"
109
- ), P(n, "interacted"), g(n);
110
- }), d = i.addNotificationResponseReceivedListener((n) => {
111
- e.log("[Knock] Expo Push Notification was interacted with"), P(
112
- n.notification,
109
+ ), P(e, "interacted"), g(e);
110
+ }), d = i.addNotificationResponseReceivedListener((e) => {
111
+ n.log("[Knock] Expo Push Notification was interacted with"), P(
112
+ e.notification,
113
113
  "interacted"
114
- ), k(n);
114
+ ), k(e);
115
115
  });
116
116
  return () => {
117
- i.removeNotificationSubscription(
118
- o
119
- ), i.removeNotificationSubscription(
120
- d
121
- );
117
+ o.remove(), d.remove();
122
118
  };
123
119
  }, [
124
120
  u,
@@ -128,9 +124,9 @@ const L = ({
128
124
  l,
129
125
  s,
130
126
  t,
131
- e
127
+ n
132
128
  ]), /* @__PURE__ */ h(
133
- m.Provider,
129
+ x.Provider,
134
130
  {
135
131
  value: {
136
132
  expoPushToken: s,
@@ -140,11 +136,11 @@ const L = ({
140
136
  onNotificationReceived: E,
141
137
  onNotificationTapped: y
142
138
  },
143
- children: x
139
+ children: N
144
140
  }
145
141
  );
146
142
  }, z = (t) => /* @__PURE__ */ h(T, { children: /* @__PURE__ */ h(L, { ...t }) }), J = () => {
147
- const t = H(m);
143
+ const t = I(x);
148
144
  if (t === void 0)
149
145
  throw new Error(
150
146
  "[Knock] useExpoPushNotifications must be used within a KnockExpoPushNotificationProvider"
@@ -1 +1 @@
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 shouldShowBanner: true,\n shouldShowList: 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 shouldShowBanner: true,\n shouldShowList: 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 | void> => {\n const messageId = notification.request.content.data?.[\n \"knock_message_id\"\n ] as string | undefined;\n\n // Skip status update if this isn't a Knock notification\n // Fixes issue: https://github.com/knocklabs/javascript/issues/589\n if (!messageId) {\n knockClient.log(\n \"[Knock] Skipping status update for non-Knock notification\",\n );\n return;\n }\n\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 autoRegister,\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","_a","useEffect","_result","_error","notificationReceivedSubscription","notificationResponseSubscription","response","jsx","KnockExpoPushNotificationProvider","props","KnockPushNotificationProvider","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 shouldShowBanner: true,\n shouldShowList: 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 shouldShowBanner: true,\n shouldShowList: 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 | void> => {\n const messageId = notification.request.content.data?.[\n \"knock_message_id\"\n ] as string | undefined;\n\n // Skip status update if this isn't a Knock notification\n // Fixes issue: https://github.com/knocklabs/javascript/issues/589\n if (!messageId) {\n knockClient.log(\n \"[Knock] Skipping status update for non-Knock notification\",\n );\n return;\n }\n\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 notificationReceivedSubscription.remove();\n notificationResponseSubscription.remove();\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 autoRegister,\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","_a","useEffect","_result","_error","notificationReceivedSubscription","notificationResponseSubscription","response","jsx","KnockExpoPushNotificationProvider","props","KnockPushNotificationProvider","useExpoPushNotifications","context","useContext"],"mappings":"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"}
@@ -1 +1 @@
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;AA8BD,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;AAoND,eAAO,MAAM,iCAAiC,EAAE,KAAK,CAAC,EAAE,CACtD,sCAAsC,CAOvC,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;AA8BD,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;AAgND,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.3.49",
3
+ "version": "0.3.50",
4
4
  "author": "@knocklabs",
5
5
  "license": "MIT",
6
6
  "main": "dist/cjs/index.js",
@@ -31,7 +31,9 @@
31
31
  "format": "prettier \"src/**/*.{js,ts,tsx}\" --write",
32
32
  "format:check": "prettier \"src/**/*.{js,ts,tsx}\" --check",
33
33
  "type:check": "tsc --noEmit",
34
- "preview": "vite preview"
34
+ "preview": "vite preview",
35
+ "test": "vitest run",
36
+ "test:watch": "vitest"
35
37
  },
36
38
  "repository": {
37
39
  "type": "git",
@@ -58,6 +60,8 @@
58
60
  },
59
61
  "devDependencies": {
60
62
  "@codecov/vite-plugin": "^1.9.1",
63
+ "@testing-library/jest-dom": "^6.8.0",
64
+ "@testing-library/react": "^16.3.0",
61
65
  "@types/react": "^19.1.8",
62
66
  "@types/react-native-htmlview": "^0.16.6",
63
67
  "@typescript-eslint/eslint-plugin": "^8.32.0",
@@ -70,12 +74,14 @@
70
74
  "expo-constants": "~17.1.7",
71
75
  "expo-device": "^7.1.4",
72
76
  "expo-notifications": "^0.31.4",
77
+ "jsdom": "^27.0.0",
73
78
  "react": "^19.0.0",
74
79
  "react-native": "^0.79.2",
75
80
  "rimraf": "^6.0.1",
76
81
  "typescript": "^5.8.3",
77
82
  "vite": "^5.4.19",
78
83
  "vite-plugin-dts": "^4.5.0",
79
- "vite-plugin-no-bundle": "^4.0.0"
84
+ "vite-plugin-no-bundle": "^4.0.0",
85
+ "vitest": "^3.1.1"
80
86
  }
81
87
  }
@@ -238,12 +238,8 @@ const InternalKnockExpoPushNotificationProvider: React.FC<
238
238
  });
239
239
 
240
240
  return () => {
241
- Notifications.removeNotificationSubscription(
242
- notificationReceivedSubscription,
243
- );
244
- Notifications.removeNotificationSubscription(
245
- notificationResponseSubscription,
246
- );
241
+ notificationReceivedSubscription.remove();
242
+ notificationResponseSubscription.remove();
247
243
  };
248
244
 
249
245
  // TODO: Remove when possible and ensure dependency array is correct