TelegramPWA/src/components/common/SeenByModal.tsx
2024-04-19 13:37:34 +04:00

113 lines
3.0 KiB
TypeScript

import React, { memo, useMemo } from '../../lib/teact/teact';
import { getActions, withGlobal } from '../../global';
import { selectChatMessage, selectTabState } from '../../global/selectors';
import buildClassName from '../../util/buildClassName';
import { formatDateAtTime } from '../../util/date/dateFormat';
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import Button from '../ui/Button';
import ListItem from '../ui/ListItem';
import Modal from '../ui/Modal';
import PrivateChatInfo from './PrivateChatInfo';
import styles from './SeenByModal.module.scss';
export type OwnProps = {
isOpen: boolean;
};
export type StateProps = {
seenByDates?: Record<string, number>;
};
const CLOSE_ANIMATION_DURATION = 100;
function SeenByModal({
isOpen,
seenByDates,
}: OwnProps & StateProps) {
const {
openChat,
closeSeenByModal,
} = getActions();
const lang = useLang();
const renderingSeenByDates = useCurrentOrPrev(seenByDates, true);
const memberIds = useMemo(() => {
if (!renderingSeenByDates) {
return undefined;
}
const result = Object.keys(renderingSeenByDates);
result.sort((leftId, rightId) => renderingSeenByDates[rightId] - renderingSeenByDates[leftId]);
return result;
}, [renderingSeenByDates]);
const handleClick = useLastCallback((userId: string) => {
closeSeenByModal();
setTimeout(() => {
openChat({ id: userId });
}, CLOSE_ANIMATION_DURATION);
});
const handleCloseSeenByModal = useLastCallback(() => {
closeSeenByModal();
});
return (
<Modal
isOpen={isOpen}
onClose={closeSeenByModal}
className={buildClassName(styles.modal, 'narrow')}
title={`Seen by ${memberIds?.length} users`}
>
<div dir={lang.isRtl ? 'rtl' : undefined}>
{memberIds && memberIds.map((userId) => (
<ListItem
key={userId}
className="chat-item-clickable scroll-item small-icon"
// eslint-disable-next-line react/jsx-no-bind
onClick={() => handleClick(userId)}
>
<PrivateChatInfo
userId={userId}
noStatusOrTyping
status={formatDateAtTime(lang, renderingSeenByDates![userId] * 1000)}
statusIcon="message-read"
/>
</ListItem>
))}
</div>
<div className="dialog-buttons mt-2">
<Button
className="confirm-dialog-button"
isText
onClick={handleCloseSeenByModal}
>
{lang('Close')}
</Button>
</div>
</Modal>
);
}
export default memo(withGlobal<OwnProps>(
(global): StateProps => {
const { chatId, messageId } = selectTabState(global).seenByModal || {};
if (!chatId || !messageId) {
return {};
}
return {
seenByDates: selectChatMessage(global, chatId, messageId)?.seenByDates,
};
},
)(SeenByModal));