fbcb740dc9
## Issue 6236 Add context menu to file page ## Notes The download button actually handles a lot of things -- generating 'streamingUrl', differences between Web and Desktop, download progress for Desktop, etc. A simpler fix would be to put something else (maybe "Share") into the overflow menu instead. Anyway, went ahead to do it per 6236, but retained the item for Desktop since we need a progress label.
219 lines
6.6 KiB
JavaScript
219 lines
6.6 KiB
JavaScript
// @flow
|
|
import { SITE_NAME, ENABLE_FILE_REACTIONS } from 'config';
|
|
import * as PAGES from 'constants/pages';
|
|
import * as MODALS from 'constants/modal_types';
|
|
import * as ICONS from 'constants/icons';
|
|
import React from 'react';
|
|
import Button from 'component/button';
|
|
import FileDownloadLink from 'component/fileDownloadLink';
|
|
import { buildURI, COLLECTIONS_CONSTS } from 'lbry-redux';
|
|
import * as RENDER_MODES from 'constants/file_render_modes';
|
|
import { useIsMobile } from 'effects/use-screensize';
|
|
import ClaimSupportButton from 'component/claimSupportButton';
|
|
import ClaimCollectionAddButton from 'component/claimCollectionAddButton';
|
|
import { useHistory } from 'react-router';
|
|
import FileReactions from 'component/fileReactions';
|
|
import { Menu, MenuButton, MenuList, MenuItem } from '@reach/menu-button';
|
|
import Icon from 'component/common/icon';
|
|
import { webDownloadClaim } from 'util/downloadClaim';
|
|
|
|
type Props = {
|
|
uri: string,
|
|
claim: StreamClaim,
|
|
openModal: (id: string, { uri: string, claimIsMine?: boolean, isSupport?: boolean }) => void,
|
|
prepareEdit: ({}, string, {}) => void,
|
|
claimIsMine: boolean,
|
|
fileInfo: FileListItem,
|
|
costInfo: ?{ cost: number },
|
|
renderMode: string,
|
|
myChannels: ?Array<ChannelClaim>,
|
|
doToast: ({ message: string }) => void,
|
|
clearPlayingUri: () => void,
|
|
isLivestreamClaim: boolean,
|
|
reactionsDisabled: boolean,
|
|
download: (string) => void,
|
|
streamingUrl: ?string,
|
|
};
|
|
|
|
function FileActions(props: Props) {
|
|
const {
|
|
fileInfo,
|
|
uri,
|
|
openModal,
|
|
claimIsMine,
|
|
claim,
|
|
costInfo,
|
|
renderMode,
|
|
prepareEdit,
|
|
myChannels,
|
|
clearPlayingUri,
|
|
doToast,
|
|
isLivestreamClaim,
|
|
reactionsDisabled,
|
|
download,
|
|
streamingUrl,
|
|
} = props;
|
|
const {
|
|
push,
|
|
location: { pathname, search },
|
|
} = useHistory();
|
|
const isMobile = useIsMobile();
|
|
const webShareable = costInfo && costInfo.cost === 0 && RENDER_MODES.WEB_SHAREABLE_MODES.includes(renderMode);
|
|
const showDelete = claimIsMine || (fileInfo && (fileInfo.written_bytes > 0 || fileInfo.blobs_completed > 0));
|
|
const hasChannels = myChannels && myChannels.length > 0;
|
|
const claimId = claim && claim.claim_id;
|
|
const { signing_channel: signingChannel } = claim;
|
|
const channelName = signingChannel && signingChannel.name;
|
|
const fileName = claim && claim.value && claim.value.source && claim.value.source.name;
|
|
|
|
// We want to use the short form uri for editing
|
|
// This is what the user is used to seeing, they don't care about the claim id
|
|
// We will select the claim id before they publish
|
|
let editUri;
|
|
if (claimIsMine) {
|
|
const uriObject: { streamName: string, streamClaimId: string, channelName?: string } = {
|
|
streamName: claim.name,
|
|
streamClaimId: claim.claim_id,
|
|
};
|
|
if (channelName) {
|
|
uriObject.channelName = channelName;
|
|
}
|
|
|
|
editUri = buildURI(uriObject);
|
|
}
|
|
|
|
const urlParams = new URLSearchParams(search);
|
|
const collectionId = urlParams.get(COLLECTIONS_CONSTS.COLLECTION_ID);
|
|
|
|
// @if TARGET='web'
|
|
const [downloadClicked, setDownloadClicked] = React.useState(false);
|
|
|
|
function handleWebDownload() {
|
|
// download() causes 'streamingUrl' to be populated.
|
|
download(uri);
|
|
setDownloadClicked(true);
|
|
}
|
|
|
|
React.useEffect(() => {
|
|
if (downloadClicked && streamingUrl) {
|
|
webDownloadClaim(streamingUrl, fileName);
|
|
}
|
|
}, [downloadClicked, streamingUrl, fileName]);
|
|
// @endif
|
|
|
|
function handleRepostClick() {
|
|
if (!hasChannels) {
|
|
clearPlayingUri();
|
|
push(`/$/${PAGES.CHANNEL_NEW}?redirect=${pathname}`);
|
|
doToast({ message: __('A channel is required to repost on %SITE_NAME%', { SITE_NAME }) });
|
|
} else {
|
|
push(`/$/${PAGES.REPOST_NEW}?from=${encodeURIComponent(uri)}&redirect=${pathname}`);
|
|
}
|
|
}
|
|
|
|
const lhsSection = (
|
|
<>
|
|
{ENABLE_FILE_REACTIONS && !reactionsDisabled && <FileReactions uri={uri} />}
|
|
<ClaimSupportButton uri={uri} fileAction />
|
|
<ClaimCollectionAddButton uri={uri} fileAction />
|
|
<Button
|
|
button="alt"
|
|
className="button--file-action"
|
|
icon={ICONS.REPOST}
|
|
label={
|
|
claim.meta.reposted > 1 ? __(`%repost_total% Reposts`, { repost_total: claim.meta.reposted }) : __('Repost')
|
|
}
|
|
description={__('Repost')}
|
|
requiresAuth={IS_WEB}
|
|
onClick={handleRepostClick}
|
|
/>
|
|
<Button
|
|
className="button--file-action"
|
|
icon={ICONS.SHARE}
|
|
label={__('Share')}
|
|
title={__('Share')}
|
|
onClick={() => openModal(MODALS.SOCIAL_SHARE, { uri, webShareable, collectionId })}
|
|
/>
|
|
</>
|
|
);
|
|
|
|
const rhsSection = (
|
|
<>
|
|
{/* @if TARGET='app' */}
|
|
<FileDownloadLink uri={uri} />
|
|
{/* @endif */}
|
|
{claimIsMine && (
|
|
<Button
|
|
className="button--file-action"
|
|
icon={ICONS.EDIT}
|
|
label={isLivestreamClaim ? __('Update') : __('Edit')}
|
|
navigate={`/$/${PAGES.UPLOAD}`}
|
|
onClick={() => {
|
|
prepareEdit(claim, editUri, fileInfo);
|
|
}}
|
|
/>
|
|
)}
|
|
{showDelete && (
|
|
<Button
|
|
title={__('Remove from your library')}
|
|
className="button--file-action"
|
|
icon={ICONS.DELETE}
|
|
description={__('Delete')}
|
|
onClick={() => openModal(MODALS.CONFIRM_FILE_REMOVE, { uri })}
|
|
/>
|
|
)}
|
|
<Menu>
|
|
<MenuButton
|
|
className="button--file-action"
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
}}
|
|
>
|
|
<Icon size={20} icon={ICONS.MORE} />
|
|
</MenuButton>
|
|
<MenuList className="menu__list">
|
|
{/* @if TARGET='web' */}
|
|
<MenuItem className="comment__menu-option" onSelect={handleWebDownload}>
|
|
<div className="menu__link">
|
|
<Icon aria-hidden icon={ICONS.DOWNLOAD} />
|
|
{__('Download')}
|
|
</div>
|
|
</MenuItem>
|
|
{/* @endif */}
|
|
{!claimIsMine && (
|
|
<MenuItem
|
|
className="comment__menu-option"
|
|
onSelect={() => push(`/$/${PAGES.REPORT_CONTENT}?claimId=${claimId}`)}
|
|
>
|
|
<div className="menu__link">
|
|
<Icon aria-hidden icon={ICONS.REPORT} />
|
|
{__('Report content')}
|
|
</div>
|
|
</MenuItem>
|
|
)}
|
|
</MenuList>
|
|
</Menu>
|
|
</>
|
|
);
|
|
|
|
if (isMobile) {
|
|
return (
|
|
<div className="media__actions">
|
|
{lhsSection}
|
|
{rhsSection}
|
|
</div>
|
|
);
|
|
} else {
|
|
return (
|
|
<div className="media__actions">
|
|
<div className="section__actions section__actions--no-margin">
|
|
{lhsSection}
|
|
{rhsSection}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
export default FileActions;
|