import React, { useMemo } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import type { Attachment, LocalMessage } from 'stream-chat';
import type { ChannelContextValue } from '../../../contexts/channelContext/ChannelContext';
import { useComponentsContext } from '../../../contexts/componentsContext/ComponentsContext';
import {
Alignment,
MessageContextValue,
useMessageContext,
} from '../../../contexts/messageContext/MessageContext';
import { useTheme } from '../../../contexts/themeContext/ThemeContext';
import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext';
import { primitives } from '../../../theme';
import { isEditedMessage, MessageStatusTypes } from '../../../utils/utils';
import { useShouldUseOverlayStyles } from '../hooks/useShouldUseOverlayStyles';
type MessageFooterComponentProps = {
date?: string | Date;
formattedDate?: string | Date;
};
type MessageFooterPropsWithContext = Pick<
MessageContextValue,
| 'alignment'
| 'members'
| 'message'
| 'showMessageStatus'
| 'lastGroupMessage'
| 'isMessageAIGenerated'
> &
MessageFooterComponentProps;
const MessageFooterWithContext = (props: MessageFooterPropsWithContext) => {
const {
alignment,
date,
formattedDate,
isMessageAIGenerated,
lastGroupMessage,
members,
message,
showMessageStatus,
} = props;
const { MessageStatus, MessageTimestamp } = useComponentsContext();
const styles = useStyles();
const {
theme: {
messageItemView: {
footer: { container, name, editedText },
},
},
} = useTheme();
const { t } = useTranslationContext();
const isAIGenerated = useMemo(
() => isMessageAIGenerated(message),
[message, isMessageAIGenerated],
);
if (lastGroupMessage === false && message.status === MessageStatusTypes.RECEIVED) {
return null;
}
const isEdited = isEditedMessage(message) && !isAIGenerated;
return (
{Object.keys(members).length > 2 && alignment === 'left' && message.user?.name ? (
{message.user.name}
) : null}
{showMessageStatus ? : null}
{isEdited ? {t('Edited')} : null}
);
};
const areEqual = (
prevProps: MessageFooterPropsWithContext,
nextProps: MessageFooterPropsWithContext,
) => {
const {
alignment: prevAlignment,
date: prevDate,
formattedDate: prevFormattedDate,
lastGroupMessage: prevLastGroupMessage,
members: prevMembers,
message: prevMessage,
showMessageStatus: prevShowMessageStatus,
} = prevProps;
const {
alignment: nextAlignment,
date: nextDate,
formattedDate: nextFormattedDate,
lastGroupMessage: nextLastGroupMessage,
members: nextMembers,
message: nextMessage,
showMessageStatus: nextShowMessageStatus,
} = nextProps;
const alignmentEqual = prevAlignment === nextAlignment;
if (!alignmentEqual) {
return false;
}
const membersEqual = Object.keys(prevMembers).length === Object.keys(nextMembers).length;
if (!membersEqual) {
return false;
}
const lastGroupMessageEqual = prevLastGroupMessage === nextLastGroupMessage;
if (!lastGroupMessageEqual) {
return false;
}
const isPrevMessageTypeDeleted = prevMessage.type === 'deleted';
const isNextMessageTypeDeleted = nextMessage.type === 'deleted';
const messageEqual =
isPrevMessageTypeDeleted === isNextMessageTypeDeleted &&
prevMessage.reply_count === nextMessage.reply_count &&
prevMessage.status === nextMessage.status &&
prevMessage.type === nextMessage.type &&
prevMessage.text === nextMessage.text &&
prevMessage.pinned === nextMessage.pinned;
if (!messageEqual) {
return false;
}
const showMessageStatusEqual = prevShowMessageStatus === nextShowMessageStatus;
if (!showMessageStatusEqual) {
return false;
}
const dateEqual = prevDate === nextDate;
if (!dateEqual) {
return false;
}
const formattedDateEqual = prevFormattedDate === nextFormattedDate;
if (!formattedDateEqual) {
return false;
}
return true;
};
const MemoizedMessageFooter = React.memo(
MessageFooterWithContext,
areEqual,
) as typeof MessageFooterWithContext;
export type MessageFooterProps = Partial> &
MessageFooterComponentProps & {
alignment?: Alignment;
lastGroupMessage?: boolean;
message?: LocalMessage;
otherAttachments?: Attachment[];
showMessageStatus?: boolean;
};
export const MessageFooter = (props: MessageFooterProps) => {
const { alignment, isMessageAIGenerated, lastGroupMessage, members, message, showMessageStatus } =
useMessageContext();
return (
);
};
const useStyles = () => {
const {
theme: { semantics },
} = useTheme();
const shouldUseOverlayStyles = useShouldUseOverlayStyles();
return useMemo(() => {
return StyleSheet.create({
container: {
maxWidth: '100%',
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'center',
paddingVertical: primitives.spacingXxs,
gap: primitives.spacingXs,
},
name: {
flexShrink: 1,
color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.chatTextUsername,
fontSize: primitives.typographyFontSizeXs,
fontWeight: primitives.typographyFontWeightSemiBold,
lineHeight: primitives.typographyLineHeightTight,
},
editedText: {
color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.chatTextTimestamp,
fontSize: primitives.typographyFontSizeXs,
fontWeight: primitives.typographyFontWeightRegular,
lineHeight: primitives.typographyLineHeightTight,
},
});
}, [
shouldUseOverlayStyles,
semantics.chatTextTimestamp,
semantics.chatTextUsername,
semantics.textOnAccent,
]);
};