diff --git a/package.json b/package.json index 296749be5..dc4ab4592 100644 --- a/package.json +++ b/package.json @@ -118,6 +118,9 @@ "react-native-webview": "*" }, "peerDependenciesMeta": { + "@react-navigation/native": { + "optional": true + }, "expo": { "optional": true } diff --git a/src/core/hooks/index.ts b/src/core/hooks/index.ts index 35d77007a..5256bbbfc 100644 --- a/src/core/hooks/index.ts +++ b/src/core/hooks/index.ts @@ -1,2 +1,3 @@ export * from './useAppStateListener'; export * from './useDeviceOrientation'; +export * from './useIsFocused'; diff --git a/src/core/hooks/useIsFocused.ts b/src/core/hooks/useIsFocused.ts new file mode 100644 index 000000000..28faf9ab2 --- /dev/null +++ b/src/core/hooks/useIsFocused.ts @@ -0,0 +1,35 @@ +/** + * A wrapper around `useIsFocused` from `@react-navigation/native` that + * gracefully falls back to `true` when react-navigation is not installed. + * + * This allows the SDK to work without requiring `@react-navigation/native` + * as a hard dependency. Users who do not use react-navigation (or do not use + * the inbox feature with navigation) will not need to install it. + * + * @see https://github.com/Iterable/react-native-sdk/issues/770 + */ + +let reactNavigationHook: (() => boolean) | undefined; + +try { + // Dynamic import via require is necessary here to gracefully handle the case + // where @react-navigation/native is not installed. + // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires + const reactNavigation = require('@react-navigation/native'); + reactNavigationHook = reactNavigation.useIsFocused; +} catch { + // @react-navigation/native is not installed +} + +/** + * Returns whether the screen is currently focused. + * + * If `@react-navigation/native` is installed, this delegates to its + * `useIsFocused` hook. Otherwise it returns `true` (always focused). + */ +export function useIsFocused(): boolean { + if (reactNavigationHook) { + return reactNavigationHook(); + } + return true; +} diff --git a/src/inbox/components/IterableInbox.tsx b/src/inbox/components/IterableInbox.tsx index 3cf44d829..317ae99a1 100644 --- a/src/inbox/components/IterableInbox.tsx +++ b/src/inbox/components/IterableInbox.tsx @@ -1,4 +1,3 @@ -import { useIsFocused } from '@react-navigation/native'; import { useEffect, useState } from 'react'; import { Animated, @@ -11,7 +10,7 @@ import { import { SafeAreaView } from 'react-native-safe-area-context'; import RNIterableAPI from '../../api'; -import { useAppStateListener, useDeviceOrientation } from '../../core'; +import { useAppStateListener, useDeviceOrientation, useIsFocused } from '../../core'; // expo throws an error if this is not imported directly due to circular // dependencies // See: https://github.com/expo/expo/issues/35100