import React, { useMemo } from 'react'; import { Pressable, StyleSheet, View } from 'react-native'; import type { ChannelPreviewProps } from './ChannelPreview'; import type { LastMessageType } from './hooks/useChannelPreviewData'; import { ChannelsContextValue, useChannelsContext, } from '../../contexts/channelsContext/ChannelsContext'; import { useComponentsContext } from '../../contexts/componentsContext/ComponentsContext'; import { useSwipeRegistryContext } from '../../contexts/swipeableContext/SwipeRegistryContext'; import { useTheme } from '../../contexts/themeContext/ThemeContext'; import { useStableCallback } from '../../hooks'; import { primitives } from '../../theme'; export type ChannelPreviewViewPropsWithContext = Pick & Pick & { /** * Formatter function for date of latest message. * @param date Message date * @returns Formatted date string * * By default today's date is shown in 'HH:mm A' format and other dates * are displayed in 'DD/MM/YY' format. props.latestMessage.created_at is the * default formatted date. This default logic is part of ChannelPreview component. */ formatLatestMessageDate?: (date: Date) => string; /** If the channel is muted. */ muted?: boolean; /** Number of unread messages on the channel */ unread?: number; lastMessage?: LastMessageType; }; const ChannelPreviewViewWithContext = (props: ChannelPreviewViewPropsWithContext) => { const { channel, formatLatestMessageDate, maxUnreadCount, muted, onSelect, unread, mutedStatusPosition, lastMessage, } = props; const { ChannelPreviewAvatar, ChannelPreviewMessage, ChannelPreviewMutedStatus, ChannelPreviewStatus, ChannelPreviewTitle, ChannelPreviewUnreadCount, } = useComponentsContext(); const { theme: { channelPreview: { container, contentContainer, lowerRow, statusContainer, upperRow, titleContainer, wrapper, }, semantics, }, } = useTheme(); const styles = useStyles(); const swipeRegistry = useSwipeRegistryContext(); const onPress = useStableCallback(() => { if (swipeRegistry?.hasOpen()) { swipeRegistry?.closeAll(); return; } if (onSelect) { onSelect(channel); } }); return ( [ styles.container, { backgroundColor: pressed && !swipeRegistry?.hasOpen() ? semantics.backgroundUtilityPressed : 'transparent', }, container, ]} testID='channel-preview-button' > {muted && mutedStatusPosition === 'inlineTitle' ? ( ) : null} {muted && mutedStatusPosition === 'trailingBottom' ? ( ) : null} ); }; export type ChannelPreviewViewProps = Partial> & Pick; const MemoizedChannelPreviewViewWithContext = React.memo( ChannelPreviewViewWithContext, ) as typeof ChannelPreviewViewWithContext; /** * This UI component displays an individual preview item for each channel in a list. It also receives all props * from the ChannelPreview component. */ export const ChannelPreviewView = (props: ChannelPreviewViewProps) => { const { forceUpdate, maxUnreadCount, onSelect, mutedStatusPosition } = useChannelsContext(); return ( ); }; ChannelPreviewView.displayName = 'ChannelPreviewView{channelPreview}'; const useStyles = () => { const { theme: { semantics }, } = useTheme(); return useMemo(() => { return StyleSheet.create({ container: { alignItems: 'center', flexDirection: 'row', padding: primitives.spacingSm, borderRadius: primitives.radiusLg, gap: primitives.spacingMd, }, contentContainer: { flex: 1, gap: primitives.spacingXxs }, upperRow: { gap: primitives.spacingMd, alignItems: 'center', flex: 1, flexDirection: 'row', justifyContent: 'space-between', }, lowerRow: { alignItems: 'center', flexDirection: 'row', justifyContent: 'space-between', }, innerRow: { alignItems: 'center', flexDirection: 'row', gap: primitives.spacingXxs, }, statusContainer: { alignItems: 'center', flexDirection: 'row', gap: primitives.spacingXs, }, titleContainer: { flexDirection: 'row', alignItems: 'center', gap: primitives.spacingXxs, flexShrink: 1, }, wrapper: { flex: 1, padding: primitives.spacingXxs, borderBottomWidth: 1, borderBottomColor: semantics.borderCoreSubtle, }, }); }, [semantics]); };