import React, { FC, useCallback, useRef, useEffect, memo, } from '../../lib/teact/teact'; import { isUserId } from '../../modules/helpers'; import InfiniteScroll from '../ui/InfiniteScroll'; import Checkbox from '../ui/Checkbox'; import InputText from '../ui/InputText'; import ListItem from '../ui/ListItem'; import PrivateChatInfo from './PrivateChatInfo'; import GroupChatInfo from './GroupChatInfo'; import PickerSelectedItem from './PickerSelectedItem'; import useInfiniteScroll from '../../hooks/useInfiniteScroll'; import useLang from '../../hooks/useLang'; import Loading from '../ui/Loading'; import './Picker.scss'; type OwnProps = { itemIds: string[]; selectedIds: string[]; filterValue?: string; filterPlaceholder?: string; notFoundText?: string; searchInputId?: string; isLoading?: boolean; noScrollRestore?: boolean; onSelectedIdsChange: (ids: string[]) => void; onFilterChange: (value: string) => void; onLoadMore?: () => void; }; // Focus slows down animation, also it breaks transition layout in Chrome const FOCUS_DELAY_MS = 500; const MAX_FULL_ITEMS = 10; const ALWAYS_FULL_ITEMS_COUNT = 5; const Picker: FC = ({ itemIds, selectedIds, filterValue, filterPlaceholder, notFoundText, searchInputId, isLoading, noScrollRestore, onSelectedIdsChange, onFilterChange, onLoadMore, }) => { // eslint-disable-next-line no-null/no-null const inputRef = useRef(null); const shouldMinimize = selectedIds.length > MAX_FULL_ITEMS; useEffect(() => { setTimeout(() => { requestAnimationFrame(() => { inputRef.current!.focus(); }); }, FOCUS_DELAY_MS); }, []); const handleItemClick = useCallback((id: string) => { const newSelectedIds = [...selectedIds]; if (newSelectedIds.includes(id)) { newSelectedIds.splice(newSelectedIds.indexOf(id), 1); } else { newSelectedIds.push(id); } onSelectedIdsChange(newSelectedIds); onFilterChange(''); }, [selectedIds, onSelectedIdsChange, onFilterChange]); const handleFilterChange = useCallback((e: React.ChangeEvent) => { const { value } = e.currentTarget; onFilterChange(value); }, [onFilterChange]); const [viewportIds, getMore] = useInfiniteScroll(onLoadMore, itemIds, Boolean(filterValue)); const lang = useLang(); return (
{selectedIds.map((id, i) => ( ))}
{viewportIds?.length ? ( {viewportIds.map((id) => ( handleItemClick(id)} ripple > {isUserId(id) ? ( ) : ( )} ))} ) : !isLoading && viewportIds && !viewportIds.length ? (

{notFoundText || 'Sorry, nothing found.'}

) : ( )}
); }; export default memo(Picker);