// @flow import * as ICONS from 'constants/icons'; import { BLOCK_LEVEL } from 'constants/comment'; import React from 'react'; import classnames from 'classnames'; import moment from 'moment'; import humanizeDuration from 'humanize-duration'; import BlockList from 'component/blockList'; import ClaimPreview from 'component/claimPreview'; import Page from 'component/page'; import Spinner from 'component/spinner'; import Button from 'component/button'; import usePersistedState from 'effects/use-persisted-state'; import ChannelBlockButton from 'component/channelBlockButton'; import ChannelMuteButton from 'component/channelMuteButton'; const VIEW = { BLOCKED: 'blocked', ADMIN: 'admin', MODERATOR: 'moderator', MUTED: 'muted', }; type Props = { mutedUris: ?Array, personalBlockList: ?Array, adminBlockList: ?Array, moderatorBlockList: ?Array, personalTimeoutMap: { [uri: string]: { blockedAt: string, bannedFor: number, banRemaining: number } }, adminTimeoutMap: { [uri: string]: { blockedAt: string, bannedFor: number, banRemaining: number } }, moderatorTimeoutMap: { [uri: string]: { blockedAt: string, bannedFor: number, banRemaining: number } }, moderatorBlockListDelegatorsMap: { [string]: Array }, fetchingModerationBlockList: boolean, fetchModBlockedList: () => void, fetchModAmIList: () => void, delegatorsById: { [string]: { global: boolean, delegators: { name: string, claimId: string } } }, myChannelClaims: ?Array, }; function ListBlocked(props: Props) { const { mutedUris, personalBlockList, adminBlockList, moderatorBlockList, personalTimeoutMap, adminTimeoutMap, moderatorTimeoutMap, moderatorBlockListDelegatorsMap: delegatorsMap, fetchingModerationBlockList, fetchModBlockedList, fetchModAmIList, delegatorsById, myChannelClaims, } = props; const [viewMode, setViewMode] = usePersistedState('blocked-muted:display', VIEW.BLOCKED); const [localDelegatorsMap, setLocalDelegatorsMap] = React.useState(undefined); const stringifiedDelegatorsMap = JSON.stringify(delegatorsMap); const stringifiedLocalDelegatorsMap = JSON.stringify(localDelegatorsMap); const isAdmin = myChannelClaims && myChannelClaims.some((c) => delegatorsById[c.claim_id] && delegatorsById[c.claim_id].global); const isModerator = myChannelClaims && myChannelClaims.some( (c) => delegatorsById[c.claim_id] && Object.keys(delegatorsById[c.claim_id].delegators).length > 0 ); // ************************************************************************** function getList(view) { switch (view) { case VIEW.BLOCKED: return personalBlockList; case VIEW.ADMIN: return adminBlockList; case VIEW.MODERATOR: return moderatorBlockList; case VIEW.MUTED: return mutedUris; } } function getActionButtons(uri) { const getDurationStr = (durationNs) => { const NANO_TO_MS = 1000000; return humanizeDuration(durationNs / NANO_TO_MS, { round: true }); }; const getBanInfoElem = (timeoutInfo) => { return (
{moment(timeoutInfo.blockedAt).format('MMMM Do, YYYY @ HH:mm')}
{getDurationStr(timeoutInfo.bannedFor)}{' '} {__('(Remaining: %duration%) --[timeout ban duration]--', { duration: getDurationStr(timeoutInfo.banRemaining), })}
); }; switch (viewMode) { case VIEW.BLOCKED: return ( <> {personalTimeoutMap[uri] && getBanInfoElem(personalTimeoutMap[uri])} ); case VIEW.ADMIN: return ( <> {adminTimeoutMap[uri] && getBanInfoElem(adminTimeoutMap[uri])} ); case VIEW.MODERATOR: const delegatorUrisForBlockedUri = localDelegatorsMap && localDelegatorsMap[uri]; if (!delegatorUrisForBlockedUri) return null; return ( <> {delegatorUrisForBlockedUri.map((delegatorUri) => { return (
    {moderatorTimeoutMap[uri] && getBanInfoElem(moderatorTimeoutMap[uri])}
); })} ); case VIEW.MUTED: return ( <> ); } } function getHelpText(view) { switch (view) { case VIEW.BLOCKED: return __( "Blocked channels will be invisible to you in the app. They will not be able to comment on your content, nor reply to your comments left on other channels' content." ); case VIEW.ADMIN: return __('This is the global block list.'); case VIEW.MODERATOR: return __('List of channels that you have blocked as a moderator, along with the list of delegators.'); case VIEW.MUTED: return __( 'Muted channels will be invisible to you in the app. They will not know they are muted and can still interact with you and your content.' ); } } function getEmptyListTitle(view) { switch (view) { case VIEW.BLOCKED: return __('You do not have any blocked channels'); case VIEW.MUTED: return __('You do not have any muted channels'); case VIEW.ADMIN: return __('You do not have any globally-blocked channels'); case VIEW.MODERATOR: return __('You do not have any blocked channels as a moderator'); } } function getEmptyListSubtitle(view) { switch (view) { case VIEW.BLOCKED: case VIEW.MUTED: return getHelpText(view); case VIEW.ADMIN: case VIEW.MODERATOR: return null; } } function isSourceListLarger(source, local) { // Comparing the length of stringified is not perfect, but what are the // chances of having different lists with the exact same length? return source && (!local || local.length < source.length); } function getViewElem(view, label, icon) { return (