// @flow import { getChannelFromClaim } from 'util/claim'; import { MenuList, MenuItem } from '@reach/menu-button'; import { parseURI } from 'util/lbryURI'; import { URL } from 'config'; import { useHistory } from 'react-router'; import * as ICONS from 'constants/icons'; import * as MODALS from 'constants/modal_types'; import ChannelThumbnail from 'component/channelThumbnail'; import Icon from 'component/common/icon'; import React from 'react'; type Props = { uri: ?string, authorUri: string, // full LBRY Channel URI: lbry://@channel#123... commentId: string, // sha256 digest identifying the comment isTopLevel: boolean, isPinned: boolean, commentIsMine: boolean, // if this comment was signed by an owned channel disableEdit?: boolean, disableRemove?: boolean, supportAmount?: any, isLiveComment: boolean, // --- select --- claim: ?Claim, claimIsMine: boolean, activeChannelClaim: ?ChannelClaim, playingUri: ?PlayingUri, moderationDelegatorsById: { [string]: { global: boolean, delegators: { name: string, claimId: string } } }, // --- perform --- doToast: ({ message: string }) => void, handleEditComment: () => void, openModal: (id: string, {}) => void, clearPlayingUri: () => void, muteChannel: (string) => void, pinComment: (string, string, boolean) => Promise, commentModAddDelegate: (string, string, ChannelClaim) => void, setQuickReply: (any) => void, }; function CommentMenuList(props: Props) { const { uri, claim, claimIsMine, authorUri, commentIsMine, commentId, activeChannelClaim, isTopLevel, isPinned, playingUri, moderationDelegatorsById, disableEdit, disableRemove, supportAmount, isLiveComment, doToast, handleEditComment, openModal, clearPlayingUri, muteChannel, pinComment, commentModAddDelegate, setQuickReply, } = props; const { location: { pathname, search }, } = useHistory(); const contentChannelClaim = getChannelFromClaim(claim); const contentChannelPermanentUrl = contentChannelClaim && contentChannelClaim.permanent_url; const activeModeratorInfo = activeChannelClaim && moderationDelegatorsById[activeChannelClaim.claim_id]; const activeChannelIsCreator = activeChannelClaim && activeChannelClaim.permanent_url === contentChannelPermanentUrl; const activeChannelIsAdmin = activeChannelClaim && activeModeratorInfo && activeModeratorInfo.global; const activeChannelIsModerator = activeChannelClaim && contentChannelClaim && activeModeratorInfo && Object.values(activeModeratorInfo.delegators).includes(contentChannelClaim.claim_id); function handleDeleteComment() { if (playingUri && playingUri.source === 'comment') { clearPlayingUri(); } openModal(MODALS.CONFIRM_REMOVE_COMMENT, { commentId, deleterClaim: activeChannelClaim, deleterIsModOrAdmin: activeChannelIsAdmin || activeChannelIsModerator, creatorClaim: commentIsMine ? undefined : contentChannelClaim, supportAmount, setQuickReply, }); } function assignAsModerator() { if (activeChannelClaim && authorUri) { const { channelName, channelClaimId } = parseURI(authorUri); if (channelName && channelClaimId) commentModAddDelegate(channelClaimId, channelName, activeChannelClaim); } } function getBlockOptionElem() { const isPersonalBlockTheOnlyOption = !activeChannelIsModerator && !activeChannelIsAdmin; const isTimeoutBlockAvailable = claimIsMine || activeChannelIsModerator; const personalPermanentBlockOnly = isPersonalBlockTheOnlyOption && !isTimeoutBlockAvailable; function getSubtitle() { if (personalPermanentBlockOnly) { return { line1: __('Prevent this channel from interacting with you.'), line2: null, }; } else { if (activeChannelIsModerator && activeChannelIsAdmin) { return { line1: __('Personal | Moderator | Admin'), line2: __('Choose a permanent or temporary ban.'), }; } else if (activeChannelIsModerator && !activeChannelIsAdmin) { return { line1: __('Personal | Moderator'), line2: __('Choose a permanent or temporary ban.'), }; } else if (!activeChannelIsModerator && activeChannelIsAdmin) { return { line1: __('Personal | Admin'), line2: __('Choose a permanent or temporary ban.'), }; } else { return { line1: null, line2: __('Choose a permanent or temporary ban.'), }; } } } const subtitle = getSubtitle(); return ( <>
{__('Block')}
{subtitle.line1 && {subtitle.line1}} {subtitle.line2 && ( {subtitle.line2} {!personalPermanentBlockOnly && } )} ); } function handleCopyCommentLink() { const urlParams = new URLSearchParams(search); urlParams.delete('lc'); urlParams.append('lc', commentId); navigator.clipboard .writeText(`${URL}${pathname}?${urlParams.toString()}`) .then(() => doToast({ message: __('Link copied.') })); } return ( {activeChannelIsCreator &&
{__('Creator tools')}
} {activeChannelIsCreator && isTopLevel && ( pinComment(commentId, claim ? claim.claim_id : '', isPinned)} > {isPinned ? __('Unpin') : __('Pin')} )} {activeChannelIsCreator && activeChannelClaim && activeChannelClaim.permanent_url !== authorUri && (
{__('Add as moderator')}
{activeChannelClaim ? __('Assign this user to moderate %channel%.', { channel: activeChannelClaim.name }) : __('Assign this user to moderate your channel.')}
)} {commentIsMine && activeChannelClaim && activeChannelClaim.permanent_url === authorUri && !disableEdit && ( {__('Edit')} )} {!disableRemove && activeChannelClaim && (activeChannelIsModerator || activeChannelIsAdmin || activeChannelClaim.permanent_url === authorUri || activeChannelClaim.permanent_url === contentChannelPermanentUrl) && (
{__('Remove')}
)} {!commentIsMine && ( <> openModal(MODALS.BLOCK_CHANNEL, { contentUri: uri, commenterUri: authorUri, offendingCommentId: commentId, }) } > {getBlockOptionElem()} muteChannel(authorUri)}>
{__('Mute')}
{activeChannelIsCreator && ( {__('Hide this channel for you only.')} )}
)} {IS_WEB && !isLiveComment && (
{__('Copy Link')}
)} {activeChannelClaim && (
{__('Interacting as %channelName%', { channelName: activeChannelClaim.name })}
)}
); } export default CommentMenuList;