TelegramPWA/src/components/main/premium/GiveawayChannelPickerModal.tsx
2024-08-29 15:52:16 +02:00

145 lines
4.4 KiB
TypeScript

import React, {
memo, useEffect, useMemo, useState,
} from '../../../lib/teact/teact';
import { getActions, getGlobal } from '../../../global';
import {
filterChatsByName, isChatChannel, isChatPublic, isChatSuperGroup,
} from '../../../global/helpers';
import { unique } from '../../../util/iteratees';
import sortChatIds from '../../common/helpers/sortChatIds';
import useFlag from '../../../hooks/useFlag';
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import PeerPicker from '../../common/pickers/PeerPicker';
import PickerModal from '../../common/pickers/PickerModal';
import ConfirmDialog from '../../ui/ConfirmDialog';
type OwnProps = {
isOpen?: boolean;
giveawayChatId?: string;
selectionLimit: number;
initialSelectedIds: string[];
onSelectedIdsConfirmed: (newSelectedIds: string[]) => void;
onClose: NoneToVoidFunction;
};
const GiveawayChannelPickerModal = ({
isOpen,
giveawayChatId,
selectionLimit,
initialSelectedIds,
onSelectedIdsConfirmed,
onClose,
}: OwnProps) => {
const { showNotification } = getActions();
const lang = useOldLang();
const [pendingChannelId, setPendingChannelId] = useState<string | undefined>(undefined);
const [searchQuery, setSearchQuery] = useState<string>('');
const [isConfirmModalOpen, openConfirmModal, closeConfirmModal] = useFlag();
const [selectedIds, setSelectedIds] = useState<string[]>(initialSelectedIds);
useEffect(() => {
setSelectedIds(initialSelectedIds);
}, [initialSelectedIds]);
const channelIds = useMemo(() => {
const global = getGlobal();
const chatsById = global.chats.byId;
const { active, archived } = global.chats.listIds;
const ids = (active || []).concat(archived || []);
return unique(ids).map((id) => chatsById[id])
.filter((chat) => (
chat && (
isChatChannel(chat) || isChatSuperGroup(chat)
) && chat.id !== giveawayChatId
)).map((chat) => chat.id);
}, [giveawayChatId]);
const displayedChannelIds = useMemo(() => {
const chatsById = getGlobal().chats.byId;
const foundChannelIds = channelIds ? filterChatsByName(lang, channelIds, chatsById, searchQuery) : [];
return sortChatIds(foundChannelIds,
false,
selectedIds);
}, [channelIds, lang, searchQuery, selectedIds]);
const handleSelectedChannelIdsChange = useLastCallback((newSelectedIds: string[]) => {
const chatsById = getGlobal().chats.byId;
const newlyAddedIds = newSelectedIds.filter((id) => !selectedIds.includes(id));
const privateLinkChannelId = newlyAddedIds.find((id) => {
const chat = chatsById[id];
return chat && !isChatPublic(chat);
});
if (selectedIds?.length >= selectionLimit) {
showNotification({
message: lang('BoostingSelectUpToWarningChannelsPlural', selectionLimit),
});
return;
}
if (privateLinkChannelId) {
setPendingChannelId(privateLinkChannelId);
openConfirmModal();
} else {
setSelectedIds(newSelectedIds);
}
});
const confirmPrivateLinkChannelSelection = useLastCallback(() => {
if (pendingChannelId) {
setSelectedIds(unique([...selectedIds, pendingChannelId]));
}
closeConfirmModal();
});
const handleModalConfirm = useLastCallback(() => {
onSelectedIdsConfirmed(selectedIds);
onClose();
});
return (
<PickerModal
isOpen={isOpen}
onClose={onClose}
title={lang('RequestPeer.ChooseChannelTitle')}
hasCloseButton
shouldAdaptToSearch
withFixedHeight
confirmButtonText={lang('Save')}
onConfirm={handleModalConfirm}
onEnter={handleModalConfirm}
>
<PeerPicker
itemIds={displayedChannelIds}
selectedIds={selectedIds}
filterValue={searchQuery}
filterPlaceholder={lang('Search')}
onSelectedIdsChange={handleSelectedChannelIdsChange}
onFilterChange={setSearchQuery}
isSearchable
withDefaultPadding
withStatus
allowMultiple
itemInputType="checkbox"
/>
<ConfirmDialog
title={lang('BoostingGiveawayPrivateChannel')}
text={lang('BoostingGiveawayPrivateChannelWarning')}
confirmLabel={lang('Add')}
isOpen={isConfirmModalOpen}
onClose={closeConfirmModal}
confirmHandler={confirmPrivateLinkChannelSelection}
/>
</PickerModal>
);
};
export default memo(GiveawayChannelPickerModal);