@knocklabs/expo 0.4.2 → 0.4.3

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,15 @@
1
1
  # @knocklabs/expo
2
2
 
3
+ ## 0.4.3
4
+
5
+ ### Patch Changes
6
+
7
+ - e154ed9: Fix Android push notification channel registration issue and add customization options. The `KnockExpoPushNotificationProvider` had a race condition where the push token was not being properly registered with Knock's channel data on Android (and potentially iOS). This was caused by checking the state value immediately after setting it, before React had a chance to update the state. Additionally, added proper Android notification channel setup using `setNotificationChannelAsync`, which is required for Android push notifications to work correctly. Apps can now customize the Android notification channel setup by providing a `setupAndroidNotificationChannel` prop.
8
+ - Updated dependencies [01d07af]
9
+ - @knocklabs/client@0.20.1
10
+ - @knocklabs/react-core@0.12.1
11
+ - @knocklabs/react-native@0.7.3
12
+
3
13
  ## 0.4.2
4
14
 
5
15
  ### Patch Changes
@@ -1,2 +1,2 @@
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;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("react/jsx-runtime"),j=require("@knocklabs/react-core"),x=require("@knocklabs/react-native"),_=require("expo-constants"),q=require("expo-device"),A=require("expo-notifications"),i=require("react"),R=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 r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const a in t)if(a!=="default"){const u=Object.getOwnPropertyDescriptor(t,a);Object.defineProperty(r,a,u.get?u:{enumerable:!0,get:()=>t[a]})}}return r.default=t,Object.freeze(r)}const d=R(_),m=v(q),s=v(A);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}),S=i.createContext(void 0);async function F(){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 I(){m.osName==="Android"&&await s.setNotificationChannelAsync("default",{name:"Default",importance:s.AndroidImportance.MAX,vibrationPattern:[0,250,250,250],lightColor:"#FF231F7C"})}async function O(t){return m.isDevice?(await t(),await F()!=="granted"?(console.warn("[Knock] Push notification permission not granted"),null):H()):(console.warn("[Knock] Must use physical device for Push Notifications"),null)}const M=({knockExpoChannelId:t,customNotificationHandler:r,setupAndroidNotificationChannel:a=I,children:u,autoRegister:p=!0})=>{const{registerPushTokenToChannel:g,unregisterPushTokenFromChannel:y}=x.usePushNotifications(),[K,C]=i.useState(null),n=j.useKnockClient(),[k,w]=i.useState(()=>()=>{}),[P,E]=i.useState(()=>()=>{}),b=i.useCallback(e=>{w(()=>e)},[]),T=i.useCallback(e=>{E(()=>e)},[]),l=i.useCallback(async()=>{try{n.log("[Knock] Registering for push notifications");const e=await O(a);return n.log(`[Knock] Token received: ${e==null?void 0:e.data}`),e!=null&&e.data?(n.log(`[Knock] Setting push token: ${e.data}`),C(e.data),e.data):null}catch(e){return console.error("[Knock] Error registering for push notifications:",e),null}},[n,a]),N=i.useCallback(async(e,f)=>{var c;const o=(c=e.request.content.data)==null?void 0:c.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(()=>{s.setNotificationHandler({handleNotification:r??D}),p&&l().then(o=>{o&&g(o,t).then(c=>{n.log("[Knock] setChannelData success")}).catch(c=>{console.error("[Knock] Error in setting push token or channel data",c)})}).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:"),N(o,"interacted"),k(o)}),f=s.addNotificationResponseReceivedListener(o=>{n.log("[Knock] Expo Push Notification was interacted with"),N(o.notification,"interacted"),P(o)});return()=>{e.remove(),f.remove()}},[l,k,P,r,p,t,n]),h.jsx(S.Provider,{value:{expoPushToken:K,registerForPushNotifications:l,registerPushTokenToChannel:g,unregisterPushTokenFromChannel:y,onNotificationReceived:b,onNotificationTapped:T},children:u})},B=t=>h.jsx(x.KnockPushNotificationProvider,{children:h.jsx(M,{...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 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
+ {"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<string | null>;\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 setupAndroidNotificationChannel?: () => Promise<void>;\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 defaultSetupAndroidNotificationChannel(): Promise<void> {\n if (Device.osName === \"Android\") {\n await Notifications.setNotificationChannelAsync(\"default\", {\n name: \"Default\",\n importance: Notifications.AndroidImportance.MAX,\n vibrationPattern: [0, 250, 250, 250],\n lightColor: \"#FF231F7C\",\n });\n }\n}\n\nasync function requestPermissionAndGetPushToken(\n setupAndroidChannel: () => Promise<void>,\n): 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 // Setup Android notification channel before requesting permissions\n await setupAndroidChannel();\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 setupAndroidNotificationChannel = defaultSetupAndroidNotificationChannel,\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<\n string | null\n > => {\n try {\n knockClient.log(`[Knock] Registering for push notifications`);\n const token = await requestPermissionAndGetPushToken(\n setupAndroidNotificationChannel,\n );\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 return token.data;\n }\n return null;\n } catch (error) {\n console.error(`[Knock] Error registering for push notifications:`, error);\n return null;\n }\n }, [knockClient, setupAndroidNotificationChannel]);\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((token) => {\n if (token) {\n registerPushTokenToChannel(token, 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 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","defaultSetupAndroidNotificationChannel","Device","requestPermissionAndGetPushToken","setupAndroidChannel","InternalKnockExpoPushNotificationProvider","knockExpoChannelId","customNotificationHandler","setupAndroidNotificationChannel","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,10 +1,10 @@
1
- import { jsx as h } from "react/jsx-runtime";
2
- import { useKnockClient as C } from "@knocklabs/react-core";
3
- import { KnockPushNotificationProvider as T, usePushNotifications as R } from "@knocklabs/react-native";
4
- import c from "expo-constants";
5
- import * as A from "expo-device";
1
+ import { jsx as l } from "react/jsx-runtime";
2
+ import { useKnockClient as A } from "@knocklabs/react-core";
3
+ import { KnockPushNotificationProvider as R, usePushNotifications as F } from "@knocklabs/react-native";
4
+ import a from "expo-constants";
5
+ import * as N from "expo-device";
6
6
  import * as i from "expo-notifications";
7
- import { createContext as H, useContext as I, useState as f, useCallback as a, useEffect as b } from "react";
7
+ import { createContext as H, useContext as I, useState as f, useCallback as c, useEffect as b } from "react";
8
8
  i.setNotificationHandler({
9
9
  handleNotification: async () => ({
10
10
  shouldShowAlert: !0,
@@ -14,14 +14,14 @@ i.setNotificationHandler({
14
14
  shouldShowList: !0
15
15
  })
16
16
  });
17
- const j = async (t) => ({
17
+ const D = async (t) => ({
18
18
  shouldShowAlert: !0,
19
19
  shouldPlaySound: !0,
20
20
  shouldSetBadge: !0,
21
21
  shouldShowBanner: !0,
22
22
  shouldShowList: !0
23
23
  }), x = H(void 0);
24
- async function q() {
24
+ async function j() {
25
25
  const { status: t } = await i.getPermissionsAsync();
26
26
  if (t !== "granted") {
27
27
  const { status: r } = await i.requestPermissionsAsync();
@@ -29,117 +29,127 @@ async function q() {
29
29
  }
30
30
  return t;
31
31
  }
32
- async function B() {
32
+ async function q() {
33
33
  try {
34
- return !c.expoConfig || !c.expoConfig.extra || !c.expoConfig.extra.eas ? (console.error(
34
+ return !a.expoConfig || !a.expoConfig.extra || !a.expoConfig.extra.eas ? (console.error(
35
35
  "[Knock] Expo Project ID is not defined in the app configuration."
36
36
  ), null) : await i.getExpoPushTokenAsync({
37
- projectId: c.expoConfig.extra.eas.projectId
37
+ projectId: a.expoConfig.extra.eas.projectId
38
38
  });
39
39
  } catch (t) {
40
40
  return console.error("[Knock] Error getting Expo push token:", t), null;
41
41
  }
42
42
  }
43
- async function D() {
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);
43
+ async function B() {
44
+ N.osName === "Android" && await i.setNotificationChannelAsync("default", {
45
+ name: "Default",
46
+ importance: i.AndroidImportance.MAX,
47
+ vibrationPattern: [0, 250, 250, 250],
48
+ lightColor: "#FF231F7C"
49
+ });
50
+ }
51
+ async function L(t) {
52
+ return N.isDevice ? (await t(), await j() !== "granted" ? (console.warn("[Knock] Push notification permission not granted"), null) : q()) : (console.warn("[Knock] Must use physical device for Push Notifications"), null);
45
53
  }
46
- const L = ({
54
+ const _ = ({
47
55
  knockExpoChannelId: t,
48
56
  customNotificationHandler: r,
49
- children: N,
50
- autoRegister: l = !0
57
+ setupAndroidNotificationChannel: h = B,
58
+ children: v,
59
+ autoRegister: p = !0
51
60
  }) => {
52
- const { registerPushTokenToChannel: p, unregisterPushTokenFromChannel: K } = R(), [s, v] = f(null), n = C(), [g, S] = f(
61
+ const { registerPushTokenToChannel: g, unregisterPushTokenFromChannel: K } = F(), [S, w] = f(null), e = A(), [k, E] = f(
53
62
  () => () => {
54
63
  }
55
- ), [k, w] = f(() => () => {
56
- }), E = a(
64
+ ), [P, y] = f(() => () => {
65
+ }), C = c(
57
66
  (o) => {
58
- S(() => o);
67
+ E(() => o);
59
68
  },
60
69
  []
61
- ), y = a(
70
+ ), T = c(
62
71
  (o) => {
63
- w(() => o);
72
+ y(() => o);
64
73
  },
65
74
  []
66
- ), u = a(async () => {
75
+ ), u = c(async () => {
67
76
  try {
68
- n.log("[Knock] Registering for push notifications");
69
- const o = await D();
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));
77
+ e.log("[Knock] Registering for push notifications");
78
+ const o = await L(
79
+ h
80
+ );
81
+ return e.log(`[Knock] Token received: ${o == null ? void 0 : o.data}`), o != null && o.data ? (e.log(`[Knock] Setting push token: ${o.data}`), w(o.data), o.data) : null;
71
82
  } catch (o) {
72
- console.error("[Knock] Error registering for push notifications:", o);
83
+ return console.error("[Knock] Error registering for push notifications:", o), null;
73
84
  }
74
- }, [n]), P = a(
85
+ }, [e, h]), m = c(
75
86
  async (o, d) => {
76
- var m;
77
- const e = (m = o.request.content.data) == null ? void 0 : m.knock_message_id;
78
- if (!e) {
79
- n.log(
87
+ var s;
88
+ const n = (s = o.request.content.data) == null ? void 0 : s.knock_message_id;
89
+ if (!n) {
90
+ e.log(
80
91
  "[Knock] Skipping status update for non-Knock notification"
81
92
  );
82
93
  return;
83
94
  }
84
- return n.messages.updateStatus(e, d);
95
+ return e.messages.updateStatus(n, d);
85
96
  },
86
- [n]
97
+ [e]
87
98
  );
88
99
  return b(() => {
89
100
  i.setNotificationHandler({
90
- handleNotification: r ?? j
91
- }), l && u().then(() => {
92
- s && p(s, t).then((e) => {
93
- n.log("[Knock] setChannelData success");
94
- }).catch((e) => {
101
+ handleNotification: r ?? D
102
+ }), p && u().then((n) => {
103
+ n && g(n, t).then((s) => {
104
+ e.log("[Knock] setChannelData success");
105
+ }).catch((s) => {
95
106
  console.error(
96
107
  "[Knock] Error in setting push token or channel data",
97
- e
108
+ s
98
109
  );
99
110
  });
100
- }).catch((e) => {
111
+ }).catch((n) => {
101
112
  console.error(
102
113
  "[Knock] Error in setting push token or channel data",
103
- e
114
+ n
104
115
  );
105
116
  });
106
- const o = i.addNotificationReceivedListener((e) => {
107
- n.log(
117
+ const o = i.addNotificationReceivedListener((n) => {
118
+ e.log(
108
119
  "[Knock] Expo Push Notification received in foreground:"
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,
120
+ ), m(n, "interacted"), k(n);
121
+ }), d = i.addNotificationResponseReceivedListener((n) => {
122
+ e.log("[Knock] Expo Push Notification was interacted with"), m(
123
+ n.notification,
113
124
  "interacted"
114
- ), k(e);
125
+ ), P(n);
115
126
  });
116
127
  return () => {
117
128
  o.remove(), d.remove();
118
129
  };
119
130
  }, [
120
131
  u,
121
- g,
122
132
  k,
133
+ P,
123
134
  r,
124
- l,
125
- s,
135
+ p,
126
136
  t,
127
- n
128
- ]), /* @__PURE__ */ h(
137
+ e
138
+ ]), /* @__PURE__ */ l(
129
139
  x.Provider,
130
140
  {
131
141
  value: {
132
- expoPushToken: s,
142
+ expoPushToken: S,
133
143
  registerForPushNotifications: u,
134
- registerPushTokenToChannel: p,
144
+ registerPushTokenToChannel: g,
135
145
  unregisterPushTokenFromChannel: K,
136
- onNotificationReceived: E,
137
- onNotificationTapped: y
146
+ onNotificationReceived: C,
147
+ onNotificationTapped: T
138
148
  },
139
- children: N
149
+ children: v
140
150
  }
141
151
  );
142
- }, z = (t) => /* @__PURE__ */ h(T, { children: /* @__PURE__ */ h(L, { ...t }) }), J = () => {
152
+ }, J = (t) => /* @__PURE__ */ l(R, { children: /* @__PURE__ */ l(_, { ...t }) }), O = () => {
143
153
  const t = I(x);
144
154
  if (t === void 0)
145
155
  throw new Error(
@@ -148,7 +158,7 @@ const L = ({
148
158
  return t;
149
159
  };
150
160
  export {
151
- z as KnockExpoPushNotificationProvider,
152
- J as useExpoPushNotifications
161
+ J as KnockExpoPushNotificationProvider,
162
+ O as useExpoPushNotifications
153
163
  };
154
164
  //# sourceMappingURL=KnockExpoPushNotificationProvider.mjs.map
@@ -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 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
+ {"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<string | null>;\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 setupAndroidNotificationChannel?: () => Promise<void>;\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 defaultSetupAndroidNotificationChannel(): Promise<void> {\n if (Device.osName === \"Android\") {\n await Notifications.setNotificationChannelAsync(\"default\", {\n name: \"Default\",\n importance: Notifications.AndroidImportance.MAX,\n vibrationPattern: [0, 250, 250, 250],\n lightColor: \"#FF231F7C\",\n });\n }\n}\n\nasync function requestPermissionAndGetPushToken(\n setupAndroidChannel: () => Promise<void>,\n): 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 // Setup Android notification channel before requesting permissions\n await setupAndroidChannel();\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 setupAndroidNotificationChannel = defaultSetupAndroidNotificationChannel,\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<\n string | null\n > => {\n try {\n knockClient.log(`[Knock] Registering for push notifications`);\n const token = await requestPermissionAndGetPushToken(\n setupAndroidNotificationChannel,\n );\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 return token.data;\n }\n return null;\n } catch (error) {\n console.error(`[Knock] Error registering for push notifications:`, error);\n return null;\n }\n }, [knockClient, setupAndroidNotificationChannel]);\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((token) => {\n if (token) {\n registerPushTokenToChannel(token, 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 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","defaultSetupAndroidNotificationChannel","Device","requestPermissionAndGetPushToken","setupAndroidChannel","InternalKnockExpoPushNotificationProvider","knockExpoChannelId","customNotificationHandler","setupAndroidNotificationChannel","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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"}
@@ -3,13 +3,14 @@ import { default as React } from 'react';
3
3
  import * as Notifications from "expo-notifications";
4
4
  export interface KnockExpoPushNotificationContextType extends KnockPushNotificationContextType {
5
5
  expoPushToken: string | null;
6
- registerForPushNotifications: () => Promise<void>;
6
+ registerForPushNotifications: () => Promise<string | null>;
7
7
  onNotificationReceived: (handler: (notification: Notifications.Notification) => void) => void;
8
8
  onNotificationTapped: (handler: (response: Notifications.NotificationResponse) => void) => void;
9
9
  }
10
10
  export interface KnockExpoPushNotificationProviderProps {
11
11
  knockExpoChannelId: string;
12
12
  customNotificationHandler?: (notification: Notifications.Notification) => Promise<Notifications.NotificationBehavior>;
13
+ setupAndroidNotificationChannel?: () => Promise<void>;
13
14
  children?: React.ReactElement;
14
15
  autoRegister?: boolean;
15
16
  }
@@ -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;AAgND,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,MAAM,GAAG,IAAI,CAAC,CAAC;IAC3D,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,+BAA+B,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,QAAQ,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC;IAC9B,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAuOD,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.4.2",
3
+ "version": "0.4.3",
4
4
  "author": "@knocklabs",
5
5
  "license": "MIT",
6
6
  "main": "dist/cjs/index.js",
@@ -51,9 +51,9 @@
51
51
  "react-native": "*"
52
52
  },
53
53
  "dependencies": {
54
- "@knocklabs/client": "^0.20.0",
55
- "@knocklabs/react-core": "^0.12.0",
56
- "@knocklabs/react-native": "^0.7.2",
54
+ "@knocklabs/client": "^0.20.1",
55
+ "@knocklabs/react-core": "^0.12.1",
56
+ "@knocklabs/react-native": "^0.7.3",
57
57
  "react-native-gesture-handler": "^2.27.1",
58
58
  "react-native-render-html": "^6.3.4",
59
59
  "react-native-svg": "^15.12.0"
@@ -19,7 +19,7 @@ import React, {
19
19
  export interface KnockExpoPushNotificationContextType
20
20
  extends KnockPushNotificationContextType {
21
21
  expoPushToken: string | null;
22
- registerForPushNotifications: () => Promise<void>;
22
+ registerForPushNotifications: () => Promise<string | null>;
23
23
  onNotificationReceived: (
24
24
  handler: (notification: Notifications.Notification) => void,
25
25
  ) => void;
@@ -61,6 +61,7 @@ export interface KnockExpoPushNotificationProviderProps {
61
61
  customNotificationHandler?: (
62
62
  notification: Notifications.Notification,
63
63
  ) => Promise<Notifications.NotificationBehavior>;
64
+ setupAndroidNotificationChannel?: () => Promise<void>;
64
65
  children?: React.ReactElement;
65
66
  autoRegister?: boolean;
66
67
  }
@@ -98,13 +99,29 @@ async function getExpoPushToken(): Promise<Notifications.ExpoPushToken | null> {
98
99
  }
99
100
  }
100
101
 
101
- async function requestPermissionAndGetPushToken(): Promise<Notifications.ExpoPushToken | null> {
102
+ async function defaultSetupAndroidNotificationChannel(): Promise<void> {
103
+ if (Device.osName === "Android") {
104
+ await Notifications.setNotificationChannelAsync("default", {
105
+ name: "Default",
106
+ importance: Notifications.AndroidImportance.MAX,
107
+ vibrationPattern: [0, 250, 250, 250],
108
+ lightColor: "#FF231F7C",
109
+ });
110
+ }
111
+ }
112
+
113
+ async function requestPermissionAndGetPushToken(
114
+ setupAndroidChannel: () => Promise<void>,
115
+ ): Promise<Notifications.ExpoPushToken | null> {
102
116
  // Check for device support
103
117
  if (!Device.isDevice) {
104
118
  console.warn("[Knock] Must use physical device for Push Notifications");
105
119
  return null;
106
120
  }
107
121
 
122
+ // Setup Android notification channel before requesting permissions
123
+ await setupAndroidChannel();
124
+
108
125
  const permissionStatus = await requestPushPermissionIfNeeded();
109
126
 
110
127
  if (permissionStatus !== "granted") {
@@ -120,6 +137,7 @@ const InternalKnockExpoPushNotificationProvider: React.FC<
120
137
  > = ({
121
138
  knockExpoChannelId,
122
139
  customNotificationHandler,
140
+ setupAndroidNotificationChannel = defaultSetupAndroidNotificationChannel,
123
141
  children,
124
142
  autoRegister = true,
125
143
  }) => {
@@ -151,19 +169,26 @@ const InternalKnockExpoPushNotificationProvider: React.FC<
151
169
  [],
152
170
  );
153
171
 
154
- const registerForPushNotifications = useCallback(async (): Promise<void> => {
172
+ const registerForPushNotifications = useCallback(async (): Promise<
173
+ string | null
174
+ > => {
155
175
  try {
156
176
  knockClient.log(`[Knock] Registering for push notifications`);
157
- const token = await requestPermissionAndGetPushToken();
177
+ const token = await requestPermissionAndGetPushToken(
178
+ setupAndroidNotificationChannel,
179
+ );
158
180
  knockClient.log(`[Knock] Token received: ${token?.data}`);
159
181
  if (token?.data) {
160
182
  knockClient.log(`[Knock] Setting push token: ${token.data}`);
161
183
  setExpoPushToken(token.data);
184
+ return token.data;
162
185
  }
186
+ return null;
163
187
  } catch (error) {
164
188
  console.error(`[Knock] Error registering for push notifications:`, error);
189
+ return null;
165
190
  }
166
- }, [knockClient]);
191
+ }, [knockClient, setupAndroidNotificationChannel]);
167
192
 
168
193
  const updateKnockMessageStatusFromNotification = useCallback(
169
194
  async (
@@ -196,9 +221,9 @@ const InternalKnockExpoPushNotificationProvider: React.FC<
196
221
 
197
222
  if (autoRegister) {
198
223
  registerForPushNotifications()
199
- .then(() => {
200
- if (expoPushToken) {
201
- registerPushTokenToChannel(expoPushToken, knockExpoChannelId)
224
+ .then((token) => {
225
+ if (token) {
226
+ registerPushTokenToChannel(token, knockExpoChannelId)
202
227
  .then((_result) => {
203
228
  knockClient.log("[Knock] setChannelData success");
204
229
  })
@@ -250,7 +275,6 @@ const InternalKnockExpoPushNotificationProvider: React.FC<
250
275
  notificationTappedHandler,
251
276
  customNotificationHandler,
252
277
  autoRegister,
253
- expoPushToken,
254
278
  knockExpoChannelId,
255
279
  knockClient,
256
280
  ]);