import React, { ReactNode, useCallback, useState } from "react"; import { GestureResponderEvent, ImageSourcePropType, StyleProp, Text, TextStyle, TouchableOpacity, View, ViewStyle, } from "react-native"; import { useTheme } from "../../../theme"; import { CometChatTheme } from "../../../theme/type"; import { Icon } from "../../icons/Icon"; import { CometChatAvatar } from "../CometChatAvatar"; import { CometChatStatusIndicator, CometChatStatusIndicatorInterface, } from "../CometChatStatusIndicator"; import { Style } from "./style"; import { DeepPartial } from "../../helper/types"; export interface CometChatListItemInterface { /** * Unique identifier for the list item. */ id: string | number; /** * URL for the avatar image. */ avatarURL?: ImageSourcePropType; /** * Fallback name for the avatar if image is not available. */ avatarName?: string; /** * Custom style for the avatar. */ avatarStyle?: CometChatTheme["avatarStyle"]; /** * Title text to display. */ title?: string; /** * Custom style for the title text. */ titleStyle?: StyleProp; /** * Custom style for the item container. */ containerStyle?: StyleProp; /** * Specifies the type for the status indicator. */ statusIndicatorType?: CometChatStatusIndicatorInterface["type"] | null; /** * Custom node to display at the beginning of the item. */ LeadingView?: ReactNode; /** * Custom node to display as the title view. */ TitleView?: ReactNode; /** * Custom node to display as the subtitle view. */ SubtitleView?: ReactNode; /** * Custom node to display at the end of the item. */ TrailingView?: ReactNode; /** * Color for the separator. */ separatorColor?: string; /** * Callback function triggered on item press. */ onPress?: Function; /** * Callback function triggered on item long press. */ onLongPress?: Function; /** * Indicates if the item is selectable. */ shouldSelect?: boolean; /** * Custom style for the container of the left (head) view. */ headViewContainerStyle?: StyleProp; /** * Custom style for the container of the trailing view. */ trailingViewContainerStyle?: StyleProp; /** * Custom style for the container wrapping title and subtitle. */ titleSubtitleContainerStyle?: StyleProp; /** * Indicates if the item is selected. */ selected?: boolean; statusIndicatorStyle?: DeepPartial } /** * CometChatListItem renders a single item in the list. * It displays an avatar with an optional status indicator, title, subtitle, and trailing view. * * @param {CometChatListItemInterface} props - Props for the list item. * @returns {JSX.Element} The rendered list item. */ export const CometChatListItem = React.memo((props: CometChatListItemInterface) => { const [translate, setTranslate] = useState(0); const theme = useTheme(); const { id, avatarURL, avatarName, title, LeadingView, SubtitleView, TrailingView, headViewContainerStyle, trailingViewContainerStyle, titleSubtitleContainerStyle, onPress, onLongPress, statusIndicatorType, titleStyle, containerStyle, avatarStyle, selected = false, shouldSelect, TitleView, statusIndicatorStyle } = props; let cancelClick = false; const CheckBoxView = useCallback(() => { return ( <> {shouldSelect && ( {selected && ( )} )} ); }, [selected, shouldSelect]); /** * Renders the title view. * * The title view. */ const getTitleView = () => { if (TitleView) return TitleView; return ( {title} ); }; /** * Handles the press event on the list item. */ const clickHandler = () => { if (!cancelClick) { if (onPress && typeof onPress === "function") { onPress(id); } } }; /** * Handles the long press event on the list item. * * @param {GestureResponderEvent} e - The long press event. */ const longPressHandler = useCallback( (e: GestureResponderEvent) => { if (!cancelClick) { if (onLongPress && typeof onLongPress === "function") { onLongPress(id, e); } } }, [onLongPress, id] ); /** * Renders the trailing view of the list item. * * @returns {JSX.Element | null} The trailing view if provided. */ const getTrailingView = () => { if (TrailingView) return ( {TrailingView} ); return null; }; let ListComponent = (onPress && typeof onPress === "function") || (onLongPress && typeof onLongPress === "function") ? TouchableOpacity : View; let listComponentProps = (onPress && typeof onPress === "function") || (onLongPress && typeof onLongPress === "function") ? { activeOpacity: 1, onPress: clickHandler, onLongPress: longPressHandler, } : {}; const getLeadingView = useCallback(() => { return ( {LeadingView ? ( LeadingView ) : avatarURL || avatarName ? ( <> ) : null} ); }, [ avatarURL, avatarName, statusIndicatorType, avatarStyle, headViewContainerStyle, theme, selected, shouldSelect, statusIndicatorStyle ]); return ( {getLeadingView()} {getTitleView()} {SubtitleView} {getTrailingView()} ); });