// @flow import { URL, SHARE_DOMAIN_URL } from 'config'; import * as ICONS from 'constants/icons'; import * as PAGES from 'constants/pages'; import * as MODALS from 'constants/modal_types'; import React from 'react'; import classnames from 'classnames'; import { Menu, MenuButton, MenuList, MenuItem } from '@reach/menu-button'; import Icon from 'component/common/icon'; import { generateShareUrl } from 'util/url'; import { useHistory } from 'react-router'; import { buildURI, parseURI, COLLECTIONS_CONSTS } from 'lbry-redux'; const SHARE_DOMAIN = SHARE_DOMAIN_URL || URL; const PAGE_VIEW_QUERY = `view`; const EDIT_PAGE = 'edit'; type SubscriptionArgs = { channelName: string, uri: string, notificationsDisabled?: boolean, }; type Props = { uri: string, channelUri: string, claim: ?Claim, openModal: (id: string, {}) => void, inline?: boolean, channelIsMuted: boolean, channelIsBlocked: boolean, doChannelMute: (string) => void, doChannelUnmute: (string) => void, doCommentModBlock: (string) => void, doCommentModUnBlock: (string) => void, isRepost: boolean, doCollectionEdit: (string, any) => void, hasClaimInWatchLater: boolean, claimInCollection: boolean, collectionName?: string, collectionId: string, isMyCollection: boolean, doToast: ({ message: string }) => void, hasExperimentalUi: boolean, claimIsMine: boolean, fileInfo: FileListItem, prepareEdit: ({}, string, {}) => void, isSubscribed: boolean, doChannelSubscribe: (SubscriptionArgs) => void, doChannelUnsubscribe: (SubscriptionArgs) => void, isChannelPage: boolean, editedCollection: Collection, }; function ClaimMenuList(props: Props) { const { uri, channelUri, claim, openModal, inline = false, doChannelMute, doChannelUnmute, channelIsMuted, channelIsBlocked, doCommentModBlock, doCommentModUnBlock, isRepost, doCollectionEdit, hasClaimInWatchLater, collectionId, collectionName, isMyCollection, doToast, hasExperimentalUi, claimIsMine, fileInfo, prepareEdit, isSubscribed, doChannelSubscribe, doChannelUnsubscribe, isChannelPage = false, editedCollection, } = props; const repostedContent = claim && claim.reposted_claim; const contentClaim = repostedContent || claim; const incognito = channelUri && !channelUri.includes('@'); const signingChannel = claim && (claim.signing_channel || claim); const permanentUrl = String(channelUri); const isChannel = !incognito && signingChannel === claim; const showDelete = claimIsMine || (fileInfo && (fileInfo.written_bytes > 0 || fileInfo.blobs_completed > 0)); const subscriptionLabel = isSubscribed ? __('Unfollow') : __('Follow'); const { push, replace } = useHistory(); if (!claim) { return null; } const shareUrl: string = generateShareUrl(SHARE_DOMAIN, uri); const isCollectionClaim = claim && claim.value_type === 'collection'; // $FlowFixMe const isPlayable = contentClaim && // $FlowFixMe contentClaim.value && // $FlowFixMe contentClaim.value.stream_type && // $FlowFixMe (contentClaim.value.stream_type === 'audio' || contentClaim.value.stream_type === 'video'); function handleFollow() { const { channelName } = parseURI(permanentUrl); const subscriptionHandler = isSubscribed ? doChannelUnsubscribe : doChannelSubscribe; subscriptionHandler({ channelName: '@' + channelName, uri: permanentUrl, notificationsDisabled: true, }); } function handleToggleMute() { if (channelIsMuted) { doChannelUnmute(channelUri); } else { doChannelMute(channelUri); } } function handleToggleBlock() { if (channelIsBlocked) { doCommentModUnBlock(channelUri); } else { doCommentModBlock(channelUri); } } function handleEdit() { if (!isChannel) { const signingChannelName = signingChannel && signingChannel.name; const uriObject: { streamName: string, streamClaimId: string, channelName?: string } = { streamName: claim.name, streamClaimId: claim.claim_id, }; if (signingChannelName) { uriObject.channelName = signingChannelName; } const editUri = buildURI(uriObject); push(`/$/${PAGES.UPLOAD}`); prepareEdit(claim, editUri, fileInfo); } else { const channelUrl = claim.name + ':' + claim.claim_id; push(`/${channelUrl}?${PAGE_VIEW_QUERY}=${EDIT_PAGE}`); } } function handleDelete() { if (!isRepost && !isChannel) { openModal(MODALS.CONFIRM_FILE_REMOVE, { uri }); } else { openModal(MODALS.CONFIRM_CLAIM_REVOKE, { claim, cb: !isRepost && (() => replace(`/$/${PAGES.CHANNELS}`)) }); } } function handleSupport() { openModal(MODALS.SEND_TIP, { uri, isSupport: true }); } function handleCopyLink() { navigator.clipboard.writeText(shareUrl); } function handleReportContent() { // $FlowFixMe push(`/$/${PAGES.REPORT_CONTENT}?claimId=${(repostedContent && repostedContent.claim_id) || claim.claim_id}`); } return ( { e.stopPropagation(); e.preventDefault(); }} > {!incognito && !isRepost && !claimIsMine && !isChannelPage && (
{subscriptionLabel}
)} {hasExperimentalUi && ( <> {/* WATCH LATER */} {isPlayable && !collectionId && ( <> { doToast({ message: __('Item %action% Watch Later', { action: hasClaimInWatchLater ? __('removed from') : __('added to'), }), }); doCollectionEdit(COLLECTIONS_CONSTS.WATCH_LATER_ID, { claims: [contentClaim], remove: hasClaimInWatchLater, type: 'playlist', }); }} >
{hasClaimInWatchLater ? __('In Watch Later') : __('Watch Later')}
)} {/* COLLECTION OPERATIONS */} {collectionId && collectionName && isCollectionClaim && ( <> {Boolean(editedCollection) && ( push(`/$/${PAGES.LIST}/${collectionId}?view=edit`)} >
{__('Publish')}
)} push(`/$/${PAGES.LIST}/${collectionId}`)}>
{__('View List')}
openModal(MODALS.COLLECTION_DELETE, { collectionId })} >
{__('Delete List')}
)} {/* CURRENTLY ONLY SUPPORT PLAYLISTS FOR PLAYABLE; LATER DIFFERENT TYPES */} {isPlayable && ( openModal(MODALS.COLLECTION_ADD, { uri, type: 'playlist' })} >
{__('Add to Lists')}
)} )} {!isChannelPage && ( <>
{__('Support')}

)} {!isMyCollection && ( <> {(!claimIsMine || channelIsBlocked) && channelUri ? ( !incognito && !isRepost && ( <>
{channelIsBlocked ? __('Unblock Channel') : __('Block Channel')}
{channelIsMuted ? __('Unmute Channel') : __('Mute Channel')}
) ) : ( <> {!isChannelPage && !isRepost && (
{__('Edit')}
)} {showDelete && (
{__('Delete')}
)} )} {!isRepost &&
} )}
{__('Copy Link')}
{!claimIsMine && !isMyCollection && (
{__('Report Content')}
)}
); } export default ClaimMenuList;