import React, { useMemo } from 'react';
import { StyleSheet, View } from 'react-native';
import { useChannelContext } from '../../../contexts/channelContext/ChannelContext';
import {
MessageContextValue,
useMessageContext,
} from '../../../contexts/messageContext/MessageContext';
import { useTheme } from '../../../contexts/themeContext/ThemeContext';
import { Check } from '../../../icons/checkmark';
import { CheckAll } from '../../../icons/checks';
import { Time } from '../../../icons/clock';
import { primitives } from '../../../theme';
import { MessageStatusTypes } from '../../../utils/utils';
import { useShouldUseOverlayStyles } from '../hooks/useShouldUseOverlayStyles';
export type MessageStatusPropsWithContext = Pick<
MessageContextValue,
'deliveredToCount' | 'message' | 'readBy'
>;
const MessageStatusWithContext = (props: MessageStatusPropsWithContext) => {
const { deliveredToCount, message, readBy } = props;
const styles = useStyles();
const {
theme: {
messageItemView: {
status: { checkAllIcon, checkIcon, container, timeIcon },
},
},
} = useTheme();
if (message.status === MessageStatusTypes.FAILED || message.type === 'error') {
return null;
}
const hasReadByGreaterThanOne = typeof readBy === 'number' && readBy > 1;
// Variables to determine the status of the message
const read = hasReadByGreaterThanOne || readBy === true;
const delivered = deliveredToCount > 1;
const sending = message.status === MessageStatusTypes.SENDING;
const sent =
message.status === MessageStatusTypes.RECEIVED &&
!delivered &&
!read &&
message.type !== 'ephemeral';
return (
{read ? (
) : delivered ? (
) : sending ? (
) : sent ? (
) : null}
);
};
const areEqual = (
prevProps: MessageStatusPropsWithContext,
nextProps: MessageStatusPropsWithContext,
) => {
const { deliveredToCount: prevDeliveredBy, message: prevMessage, readBy: prevReadBy } = prevProps;
const { deliveredToCount: nextDeliveredBy, message: nextMessage, readBy: nextReadBy } = nextProps;
const deliveredByEqual = prevDeliveredBy === nextDeliveredBy;
if (!deliveredByEqual) {
return false;
}
const readByEqual = prevReadBy === nextReadBy;
if (!readByEqual) {
return false;
}
const messageEqual =
prevMessage.status === nextMessage.status && prevMessage.type === nextMessage.type;
if (!messageEqual) {
return false;
}
return true;
};
const MemoizedMessageStatus = React.memo(
MessageStatusWithContext,
areEqual,
) as typeof MessageStatusWithContext;
export type MessageStatusProps = Partial;
export const MessageStatus = (props: MessageStatusProps) => {
const { channel } = useChannelContext();
const { deliveredToCount, message, readBy } = useMessageContext();
const channelMembersCount = Object.keys(channel?.state.members).length;
return (
);
};
MessageStatus.displayName = 'MessageStatus{messageItemView{status}}';
const useStyles = () => {
const {
theme: { semantics },
} = useTheme();
const shouldUseOverlayStyles = useShouldUseOverlayStyles();
return useMemo(() => {
return StyleSheet.create({
readByCount: {
color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.accentPrimary,
fontSize: primitives.typographyFontSizeXs,
fontWeight: primitives.typographyFontWeightRegular,
lineHeight: primitives.typographyLineHeightTight,
},
container: {
alignItems: 'center',
flexDirection: 'row',
gap: primitives.spacingXxs,
},
readCheck: {
color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.accentPrimary,
},
deliveredCheck: {
color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.chatTextTimestamp,
},
sendingCheck: {
color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.chatTextTimestamp,
},
sentCheck: {
color: shouldUseOverlayStyles ? semantics.textOnAccent : semantics.chatTextTimestamp,
},
});
}, [shouldUseOverlayStyles, semantics]);
};