import { useIsFocused } from '@react-navigation/native'; import { useEffect, useState } from 'react'; import { Animated, NativeEventEmitter, NativeModules, Platform, StyleSheet, Text, View, } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { useAppStateListener, useDeviceOrientation } from '../../core'; // expo throws an error if this is not imported directly due to circular // dependencies // See: https://github.com/expo/expo/issues/35100 import { Iterable } from '../../core/classes/Iterable'; import { IterableInAppDeleteSource, IterableInAppLocation } from '../../inApp'; import { IterableInboxDataModel } from '../classes'; import { ITERABLE_INBOX_COLORS } from '../constants'; import type { IterableInboxCustomizations, IterableInboxImpressionRowInfo, IterableInboxRowViewModel, } from '../types'; import { IterableInboxEmptyState } from './IterableInboxEmptyState'; import { IterableInboxMessageDisplay } from './IterableInboxMessageDisplay'; import { IterableInboxMessageList, type IterableInboxMessageListProps, } from './IterableInboxMessageList'; const RNIterableAPI = NativeModules.RNIterableAPI; const RNEventEmitter = new NativeEventEmitter(RNIterableAPI); const DEFAULT_HEADLINE_HEIGHT = 60; const ANDROID_HEADLINE_HEIGHT = 70; const HEADLINE_PADDING_LEFT_PORTRAIT = 30; const HEADLINE_PADDING_LEFT_LANDSCAPE = 70; /** * Props for the IterableInbox component. */ export interface IterableInboxProps extends Partial< Pick > { /** * Flag which, when switched, returns a user to their inbox from _within_ the * inbox component (from the details of the particular message to the message * list) if the inbox is already in view. * * @remarks * Let's say you have bottom tabs in your app, and one of them is the inbox. * If you click on a message, you may want to be able to return to the inbox * by clicking on the bottom tab inbox icon. * * If this prop is included and correctly set up, clicking on the bottom inbox * tab when a message is in focus will return the user to the inbox. * * If this prop is **NOT** included, clicking on the bottom inbox tab when a * message is in focus will have no effect. * * @example * ```tsx * import { NavigationContainer } from '@react-navigation/native'; * import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; * import { IterableInbox} from '@iterable/react-native-sdk/js/Iterable'; * * const Tab = createBottomTabNavigator(); * * const MyNavigation = () => { * const [isInbox, setIsInbox] = useState(false); * const [returnToInboxTrigger, setReturnToInboxTrigger] = useState(false); * * return ( * * * setIsInbox(false)}} * /> * { * // if this is true, then the inbox is already displayed, so * // go back to the message list if it is not already in view * if (isInbox) { * setReturnToInboxTrigger(!returnToInboxTrigger); * } * setIsInbox(true); * } * }} * > * {() => ( * * )} * * setIsInbox(false)}} * /> * * * ); * } * ``` */ returnToInboxTrigger?: boolean; /** Customization for the look and feel of the inbox. */ customizations?: IterableInboxCustomizations; /** * The height of the tab bar. * * If your app uses custom tab bar dimensions, provide this value to make sure that the inbox component lays out as expected. */ tabBarHeight?: number; /** * The padding of the tab bar. * * If your app uses custom tab bar dimensions, provide this value to make sure that the inbox component lays out as expected. */ tabBarPadding?: number; /** * Is safe area mode enabled? * * @remarks * This indicates whether or not the inbox should be displayed inside a React * Native [`SafeAreaView`](https://reactnative.dev/docs/safeareaview). * * If the parent of the inbox component is already inside a `SafeAreaView`, set * this to `false` as another `SafeAreaView` is not needed. * * @example * ```tsx * // Safe area mode should be `true` as it is NOT already inside a `SafeAreaView` * const MyInbox = () => ; * * // Safe area mode should be `false` as it is already inside a `SafeAreaView` * const MyInbox = () => ( * * * * ); * ``` */ safeAreaMode?: boolean; /** Should the navigation title be shown? */ showNavTitle?: boolean; } /** * The `IterableInbox` component is responsible for displaying an inbox of messages. * It handles fetching messages, displaying them in a list, and showing individual message details. * It also manages the state of the inbox, including loading state, selected message, and visible message impressions. * * @example * ```tsx * const [visible, setVisible] = useState(false); * * return ( * <> *