You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
session-desktop/ts/components/dialog/blockOrUnblock/BlockOrUnblockDialog.tsx

115 lines
4.2 KiB
TypeScript

import { useDispatch } from 'react-redux';
import { isEmpty } from 'lodash';
import { useCallback } from 'react';
import useAsyncFn from 'react-use/lib/useAsyncFn';
import { useHotkey } from '../../../hooks/useHotkey';
import { useConversationsNicknameRealNameOrShortenPubkey } from '../../../hooks/useParamSelector';
import { updateBlockOrUnblockModal } from '../../../state/ducks/modalDialog';
import { BlockedNumberController } from '../../../util';
import { SessionWrapperModal } from '../../SessionWrapperModal';
import { Flex } from '../../basic/Flex';
import { Localizer } from '../../basic/Localizer';
import { SessionButton, SessionButtonColor, SessionButtonType } from '../../basic/SessionButton';
import { StyledModalDescriptionContainer } from '../shared/ModalDescriptionContainer';
import { BlockOrUnblockModalState } from './BlockOrUnblockModalState';
import type { LocalizerComponentPropsObject } from '../../../localization/localeTools';
type ModalState = NonNullable<BlockOrUnblockModalState>;
function getUnblockTokenAndArgs(names: Array<string>): LocalizerComponentPropsObject {
// multiple unblock is supported
switch (names.length) {
case 1:
return { token: 'blockUnblockName', args: { name: names[0] } } as const;
case 2:
return { token: 'blockUnblockNameTwo', args: { name: names[0] } } as const;
default:
return {
token: 'blockUnblockNameMultiple',
args: { name: names[0], count: names.length - 1 },
} as const;
}
}
function useBlockUnblockI18nDescriptionArgs({
action,
pubkeys,
}: Pick<ModalState, 'action' | 'pubkeys'>): LocalizerComponentPropsObject {
const names = useConversationsNicknameRealNameOrShortenPubkey(pubkeys);
if (!pubkeys.length) {
throw new Error('useI18nDescriptionArgsForAction called with empty list of pubkeys');
}
if (action === 'block') {
if (pubkeys.length !== 1 || names.length !== 1) {
throw new Error('we can only block a single user at a time');
}
return { token: 'blockDescription', args: { name: names[0] } } as const;
}
return getUnblockTokenAndArgs(names);
}
export const BlockOrUnblockDialog = ({ pubkeys, action, onConfirmed }: NonNullable<ModalState>) => {
const dispatch = useDispatch();
const localizedAction = action === 'block' ? window.i18n('block') : window.i18n('blockUnblock');
const args = useBlockUnblockI18nDescriptionArgs({ action, pubkeys });
const closeModal = useCallback(() => {
dispatch(updateBlockOrUnblockModal(null));
}, [dispatch]);
useHotkey('Escape', closeModal);
const [, onConfirm] = useAsyncFn(async () => {
if (action === 'block') {
// we never block more than one user from the UI, so this is not very useful, just a type guard
for (let index = 0; index < pubkeys.length; index++) {
const pubkey = pubkeys[index];
// TODO: make BlockedNumberController.block take an array and do the change in a single call.
// eslint-disable-next-line no-await-in-loop
await BlockedNumberController.block(pubkey);
}
} else {
await BlockedNumberController.unblockAll(pubkeys);
}
closeModal();
onConfirmed?.();
}, [action, onConfirmed, pubkeys]);
if (isEmpty(pubkeys)) {
closeModal();
return null;
}
return (
<SessionWrapperModal showExitIcon={true} title={localizedAction} onClose={closeModal}>
<StyledModalDescriptionContainer data-testid="modal-description">
<Localizer {...args} />
</StyledModalDescriptionContainer>
<Flex container={true} flexDirection="column" alignItems="center">
<Flex container={true}>
<div className="session-modal__button-group">
<SessionButton
buttonType={SessionButtonType.Simple}
buttonColor={SessionButtonColor.Danger}
onClick={onConfirm}
text={localizedAction}
dataTestId="session-confirm-ok-button"
/>
<SessionButton
buttonType={SessionButtonType.Simple}
buttonColor={SessionButtonColor.White}
onClick={closeModal}
text={window.i18n('cancel')}
dataTestId="session-confirm-cancel-button"
/>
</div>
</Flex>
</Flex>
</SessionWrapperModal>
);
};