155 lines
4.2 KiB
TypeScript
155 lines
4.2 KiB
TypeScript
import type { FC } from '../../../lib/teact/teact';
|
|
import { memo, useCallback, useMemo } from '../../../lib/teact/teact';
|
|
import { getActions, getGlobal, withGlobal } from '../../../global';
|
|
|
|
import { isUserBot } from '../../../global/helpers';
|
|
import { filterPeersByQuery } from '../../../global/helpers/peers';
|
|
import { selectTabState } from '../../../global/selectors';
|
|
import { unique } from '../../../util/iteratees';
|
|
import sortChatIds from '../../common/helpers/sortChatIds';
|
|
|
|
import useHistoryBack from '../../../hooks/useHistoryBack';
|
|
import useOldLang from '../../../hooks/useOldLang';
|
|
|
|
import Icon from '../../common/icons/Icon';
|
|
import PeerPicker from '../../common/pickers/PeerPicker';
|
|
import Button from '../../ui/Button';
|
|
import FloatingActionButton from '../../ui/FloatingActionButton';
|
|
|
|
export type OwnProps = {
|
|
isChannel?: boolean;
|
|
isActive: boolean;
|
|
selectedMemberIds: string[];
|
|
onSelectedMemberIdsChange: (ids: string[]) => void;
|
|
onNextStep: () => void;
|
|
onReset: () => void;
|
|
};
|
|
|
|
type StateProps = {
|
|
localContactIds?: string[];
|
|
searchQuery?: string;
|
|
isSearching?: boolean;
|
|
localPeerIds?: string[];
|
|
globalPeerIds?: string[];
|
|
};
|
|
|
|
const NewChatStep1: FC<OwnProps & StateProps> = ({
|
|
isChannel,
|
|
isActive,
|
|
selectedMemberIds,
|
|
localContactIds,
|
|
searchQuery,
|
|
isSearching,
|
|
localPeerIds,
|
|
globalPeerIds,
|
|
onSelectedMemberIdsChange,
|
|
onNextStep,
|
|
onReset,
|
|
}) => {
|
|
const {
|
|
setGlobalSearchQuery,
|
|
} = getActions();
|
|
|
|
const lang = useOldLang();
|
|
|
|
useHistoryBack({
|
|
isActive,
|
|
onBack: onReset,
|
|
});
|
|
|
|
const handleFilterChange = useCallback((query: string) => {
|
|
setGlobalSearchQuery({ query });
|
|
}, []);
|
|
|
|
const displayedIds = useMemo(() => {
|
|
// No need for expensive global updates on users, so we avoid them
|
|
const usersById = getGlobal().users.byId;
|
|
const foundContactIds = localContactIds
|
|
? filterPeersByQuery({ ids: localContactIds, query: searchQuery, type: 'user' }) : [];
|
|
|
|
return sortChatIds(
|
|
unique([
|
|
...foundContactIds,
|
|
...(localPeerIds || []),
|
|
...(globalPeerIds || []),
|
|
]).filter((contactId) => {
|
|
const user = usersById[contactId];
|
|
|
|
return user && !user.isSelf && (user.canBeInvitedToGroup || !isUserBot(user));
|
|
}),
|
|
false,
|
|
selectedMemberIds,
|
|
);
|
|
}, [localContactIds, searchQuery, localPeerIds, globalPeerIds, selectedMemberIds]);
|
|
|
|
const handleNextStep = useCallback(() => {
|
|
setGlobalSearchQuery({ query: '' });
|
|
onNextStep();
|
|
}, [onNextStep]);
|
|
|
|
return (
|
|
<div className="NewChat step-1">
|
|
<div className="left-header">
|
|
<Button
|
|
round
|
|
size="smaller"
|
|
color="translucent"
|
|
onClick={onReset}
|
|
ariaLabel="Return to Chat List"
|
|
>
|
|
<Icon name="arrow-left" />
|
|
</Button>
|
|
<h3>{lang('GroupAddMembers')}</h3>
|
|
</div>
|
|
<div className="NewChat-inner step-1">
|
|
<PeerPicker
|
|
itemIds={displayedIds}
|
|
selectedIds={selectedMemberIds}
|
|
filterValue={searchQuery}
|
|
filterPlaceholder={lang('SendMessageTo')}
|
|
searchInputId="new-group-picker-search"
|
|
isLoading={isSearching}
|
|
isSearchable
|
|
allowMultiple
|
|
withStatus
|
|
itemInputType="checkbox"
|
|
withDefaultPadding
|
|
onSelectedIdsChange={onSelectedMemberIdsChange}
|
|
onFilterChange={handleFilterChange}
|
|
/>
|
|
|
|
<FloatingActionButton
|
|
isShown
|
|
onClick={handleNextStep}
|
|
ariaLabel={isChannel ? 'Continue To Channel Info' : 'Continue To Group Info'}
|
|
>
|
|
<Icon name="arrow-right" />
|
|
</FloatingActionButton>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default memo(withGlobal<OwnProps>(
|
|
(global): Complete<StateProps> => {
|
|
const { userIds: localContactIds } = global.contactList || {};
|
|
|
|
const {
|
|
query: searchQuery,
|
|
fetchingStatus,
|
|
globalResults,
|
|
localResults,
|
|
} = selectTabState(global).globalSearch;
|
|
const { peerIds: globalPeerIds } = globalResults || {};
|
|
const { peerIds: localPeerIds } = localResults || {};
|
|
|
|
return {
|
|
localContactIds,
|
|
searchQuery,
|
|
isSearching: fetchingStatus?.chats,
|
|
globalPeerIds,
|
|
localPeerIds,
|
|
};
|
|
},
|
|
)(NewChatStep1));
|