// @flow import React from 'react'; import classnames from 'classnames'; import parseDuration from 'parse-duration'; import Button from 'component/button'; import ChannelThumbnail from 'component/channelThumbnail'; import ClaimPreview from 'component/claimPreview'; import Card from 'component/common/card'; import { FormField } from 'component/common/form'; import Icon from 'component/common/icon'; import * as ICONS from 'constants/icons'; import usePersistedState from 'effects/use-persisted-state'; import { Modal } from 'modal/modal'; import { getChannelFromClaim } from 'util/claim'; const TAB = { PERSONAL: 'personal', MODERATOR: 'moderator', ADMIN: 'admin', }; const BLOCK = { PERMANENT: 'permanent', TIMEOUT: 'timeout', }; type Props = { contentUri: string, commenterUri: string, // --- select --- activeChannelClaim: ?ChannelClaim, contentClaim: ?Claim, moderationDelegatorsById: { [string]: { global: boolean, delegators: { name: string, claimId: string } } }, // --- perform --- closeModal: () => void, commentModBlock: (string, ?number) => void, commentModBlockAsAdmin: (string, string, ?number) => void, commentModBlockAsModerator: (string, string, string, ?number) => void, }; export default function ModalBlockChannel(props: Props) { const { commenterUri, activeChannelClaim, contentClaim, moderationDelegatorsById, closeModal, commentModBlock, commentModBlockAsAdmin, commentModBlockAsModerator, } = props; const contentChannelClaim = getChannelFromClaim(contentClaim); const activeModeratorInfo = activeChannelClaim && moderationDelegatorsById[activeChannelClaim.claim_id]; const activeChannelIsAdmin = activeChannelClaim && activeModeratorInfo && activeModeratorInfo.global; const activeChannelIsModerator = activeChannelClaim && contentChannelClaim && activeModeratorInfo && Object.values(activeModeratorInfo.delegators).includes(contentChannelClaim.claim_id); const [tab, setTab] = usePersistedState('ModalBlockChannel:tab', TAB.PERSONAL); const [blockType, setBlockType] = usePersistedState('ModalBlockChannel:blockType', BLOCK.PERMANENT); const [timeoutInput, setTimeoutInput] = usePersistedState('ModalBlockChannel:timeoutInput', '10m'); const [timeoutInputErr, setTimeoutInputErr] = React.useState(''); const [timeoutSec, setTimeoutSec] = React.useState(-1); const isPersonalTheOnlyTab = !activeChannelIsModerator && !activeChannelIsAdmin; const isTimeoutAvail = (contentClaim && contentClaim.is_my_output) || activeChannelIsModerator; const blockButtonDisabled = blockType === BLOCK.TIMEOUT && timeoutSec < 1; // ************************************************************************** // ************************************************************************** // Check settings validity on mount. React.useEffect(() => { if ( isPersonalTheOnlyTab || (tab === TAB.MODERATOR && !activeChannelIsModerator) || (tab === TAB.ADMIN && !activeChannelIsAdmin) ) { setTab(TAB.PERSONAL); } if (!isTimeoutAvail && blockType === BLOCK.TIMEOUT) { setBlockType(BLOCK.PERMANENT); } }, []); // eslint-disable-line react-hooks/exhaustive-deps // 'timeoutInput' to 'timeoutSec' conversion. React.useEffect(() => { const handleInvalidInput = (errMsg: string) => { if (timeoutSec !== -1) { setTimeoutSec(-1); } if (timeoutInputErr !== errMsg) { setTimeoutInputErr(errMsg); } }; const handleValidInput = (seconds) => { if (seconds !== timeoutSec) { setTimeoutSec(seconds); } if (timeoutInputErr) { setTimeoutInputErr(''); } }; if (!timeoutInput) { handleValidInput(-1); // Reset return; } const ONE_HUNDRED_YEARS_IN_SECONDS = 3154000000; const seconds = parseDuration(timeoutInput, 's'); if (Number.isInteger(seconds) && seconds > 0) { if (seconds > ONE_HUNDRED_YEARS_IN_SECONDS) { handleInvalidInput(__('Wow, banned for more than 100 years?')); } else { handleValidInput(seconds); } } else { handleInvalidInput(__('Invalid duration.')); } }, [timeoutInput, timeoutInputErr, timeoutSec]); // ************************************************************************** // ************************************************************************** function getTabElem(value, label) { return (