2024-12-29 11:58:54 +01:00

174 lines
5.4 KiB
TypeScript

import type { FC } from '../../../lib/teact/teact';
import React, { memo, useCallback, useMemo } from '../../../lib/teact/teact';
import { getActions, getGlobal } from '../../../global';
import type { GlobalState } from '../../../global/types';
import type { CustomPeer } from '../../../types';
import { ARCHIVED_FOLDER_ID } from '../../../config';
import { getChatTitle } from '../../../global/helpers';
import buildClassName from '../../../util/buildClassName';
import { compact } from '../../../util/iteratees';
import { formatIntegerCompact } from '../../../util/textFormat';
import renderText from '../../common/helpers/renderText';
import { useFolderManagerForOrderedIds, useFolderManagerForUnreadCounters } from '../../../hooks/useFolderManager';
import useOldLang from '../../../hooks/useOldLang';
import Avatar from '../../common/Avatar';
import Icon from '../../common/icons/Icon';
import Badge from '../../ui/Badge';
import ListItem, { type MenuItemContextAction } from '../../ui/ListItem';
import styles from './Archive.module.scss';
type OwnProps = {
archiveSettings: GlobalState['archiveSettings'];
onDragEnter?: NoneToVoidFunction;
onClick?: NoneToVoidFunction;
};
const PREVIEW_SLICE = 5;
const ARCHIVE_CUSTOM_PEER: CustomPeer = {
isCustomPeer: true,
title: 'Archived Chats',
avatarIcon: 'archive-filled',
customPeerAvatarColor: '#9EAAB5',
};
const Archive: FC<OwnProps> = ({
archiveSettings,
onDragEnter,
onClick,
}) => {
const { updateArchiveSettings } = getActions();
const lang = useOldLang();
const orderedChatIds = useFolderManagerForOrderedIds(ARCHIVED_FOLDER_ID);
const unreadCounters = useFolderManagerForUnreadCounters();
const archiveUnreadCount = unreadCounters[ARCHIVED_FOLDER_ID]?.chatsCount;
const previewItems = useMemo(() => {
if (!orderedChatIds?.length) return lang('Loading');
const chatsById = getGlobal().chats.byId;
return orderedChatIds.slice(0, PREVIEW_SLICE).map((chatId, i, arr) => {
const isLast = i === arr.length - 1;
const chat = chatsById[chatId];
if (!chat) {
return undefined;
}
const title = getChatTitle(lang, chat);
return (
<>
<span className={buildClassName(styles.chat, archiveUnreadCount && chat.unreadCount && styles.unread)}>
{renderText(title)}
</span>
{isLast ? '' : ', '}
</>
);
});
}, [orderedChatIds, lang, archiveUnreadCount]);
const contextActions = useMemo(() => {
const actionMinimize = !archiveSettings.isMinimized && {
title: lang('lng_context_archive_collapse'),
icon: 'collapse',
handler: () => {
updateArchiveSettings({ isMinimized: true });
},
} satisfies MenuItemContextAction;
const actionExpand = archiveSettings.isMinimized && {
title: lang('lng_context_archive_expand'),
icon: 'expand',
handler: () => {
updateArchiveSettings({ isMinimized: false });
},
} satisfies MenuItemContextAction;
const actionHide = {
title: lang('lng_context_archive_to_menu'),
icon: 'archive-to-main',
handler: () => {
updateArchiveSettings({ isHidden: true });
},
} satisfies MenuItemContextAction;
return compact([actionMinimize, actionExpand, actionHide]);
}, [archiveSettings.isMinimized, lang, updateArchiveSettings]);
const handleDragEnter = useCallback((e) => {
e.preventDefault();
onDragEnter?.();
}, [onDragEnter]);
function renderCollapsed() {
return (
<div className={buildClassName(styles.info, 'info')}>
<div className="info-row">
<div className={buildClassName('title', styles.title)}>
<h3 dir="auto" className={buildClassName(styles.name, 'fullName')}>
<Icon name="archive-filled" className={styles.icon} />
{lang('ArchivedChats')}
</h3>
</div>
<Badge
className={styles.unreadCount}
text={archiveUnreadCount ? formatIntegerCompact(archiveUnreadCount) : undefined}
/>
</div>
</div>
);
}
function renderRegular() {
return (
<>
<div className={buildClassName('status', styles.avatarWrapper)}>
<Avatar peer={ARCHIVE_CUSTOM_PEER} />
</div>
<div className={buildClassName(styles.info, 'info')}>
<div className="info-row">
<div className={buildClassName('title', styles.title)}>
<h3 dir="auto" className={buildClassName(styles.name, 'fullName')}>{lang('ArchivedChats')}</h3>
</div>
</div>
<div className="subtitle">
<div className={buildClassName('status', styles.chatsPreview)}>
{previewItems}
</div>
<Badge
className={styles.unreadCount}
text={archiveUnreadCount ? formatIntegerCompact(archiveUnreadCount) : undefined}
/>
</div>
</div>
</>
);
}
return (
<ListItem
onClick={onClick}
onDragEnter={handleDragEnter}
className={buildClassName(
styles.root,
archiveSettings.isMinimized && styles.minimized,
'chat-item-clickable',
'chat-item-archive',
)}
buttonClassName={styles.button}
contextActions={contextActions}
withPortalForMenu
>
{archiveSettings.isMinimized ? renderCollapsed() : renderRegular()}
</ListItem>
);
};
export default memo(Archive);