Move 'Download' and 'Report Content' into overflow menu.
## 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.
This commit is contained in:
parent
337cfd8769
commit
fbcb740dc9
4 changed files with 80 additions and 21 deletions
|
@ -7,12 +7,13 @@ import {
|
||||||
selectMyChannelClaims,
|
selectMyChannelClaims,
|
||||||
makeSelectClaimIsStreamPlaceholder,
|
makeSelectClaimIsStreamPlaceholder,
|
||||||
makeSelectTagInClaimOrChannelForUri,
|
makeSelectTagInClaimOrChannelForUri,
|
||||||
|
makeSelectStreamingUrlForUri,
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import { DISABLE_COMMENTS_TAG } from 'constants/tags';
|
import { DISABLE_COMMENTS_TAG } from 'constants/tags';
|
||||||
import { makeSelectCostInfoForUri } from 'lbryinc';
|
import { makeSelectCostInfoForUri } from 'lbryinc';
|
||||||
import { doSetPlayingUri } from 'redux/actions/content';
|
import { doSetPlayingUri, doPlayUri } from 'redux/actions/content';
|
||||||
import { doToast } from 'redux/actions/notifications';
|
import { doToast } from 'redux/actions/notifications';
|
||||||
import { doOpenModal, doSetActiveChannel, doSetIncognito } from 'redux/actions/app';
|
import { doOpenModal, doSetActiveChannel, doSetIncognito, doAnalyticsView } from 'redux/actions/app';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import FileActions from './view';
|
import FileActions from './view';
|
||||||
import { makeSelectFileRenderModeForUri } from 'redux/selectors/content';
|
import { makeSelectFileRenderModeForUri } from 'redux/selectors/content';
|
||||||
|
@ -26,6 +27,7 @@ const select = (state, props) => ({
|
||||||
myChannels: selectMyChannelClaims(state),
|
myChannels: selectMyChannelClaims(state),
|
||||||
isLivestreamClaim: makeSelectClaimIsStreamPlaceholder(props.uri)(state),
|
isLivestreamClaim: makeSelectClaimIsStreamPlaceholder(props.uri)(state),
|
||||||
reactionsDisabled: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_COMMENTS_TAG)(state),
|
reactionsDisabled: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_COMMENTS_TAG)(state),
|
||||||
|
streamingUrl: makeSelectStreamingUrlForUri(props.uri)(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = (dispatch) => ({
|
const perform = (dispatch) => ({
|
||||||
|
@ -42,6 +44,7 @@ const perform = (dispatch) => ({
|
||||||
},
|
},
|
||||||
clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })),
|
clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })),
|
||||||
doToast: (options) => dispatch(doToast(options)),
|
doToast: (options) => dispatch(doToast(options)),
|
||||||
|
download: (uri) => dispatch(doPlayUri(uri, false, true, () => dispatch(doAnalyticsView(uri)))),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, perform)(FileActions);
|
export default connect(select, perform)(FileActions);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { SIMPLE_SITE, SITE_NAME, ENABLE_FILE_REACTIONS } from 'config';
|
import { SITE_NAME, ENABLE_FILE_REACTIONS } from 'config';
|
||||||
import * as PAGES from 'constants/pages';
|
import * as PAGES from 'constants/pages';
|
||||||
import * as MODALS from 'constants/modal_types';
|
import * as MODALS from 'constants/modal_types';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
|
@ -13,6 +13,9 @@ import ClaimSupportButton from 'component/claimSupportButton';
|
||||||
import ClaimCollectionAddButton from 'component/claimCollectionAddButton';
|
import ClaimCollectionAddButton from 'component/claimCollectionAddButton';
|
||||||
import { useHistory } from 'react-router';
|
import { useHistory } from 'react-router';
|
||||||
import FileReactions from 'component/fileReactions';
|
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 = {
|
type Props = {
|
||||||
uri: string,
|
uri: string,
|
||||||
|
@ -28,6 +31,8 @@ type Props = {
|
||||||
clearPlayingUri: () => void,
|
clearPlayingUri: () => void,
|
||||||
isLivestreamClaim: boolean,
|
isLivestreamClaim: boolean,
|
||||||
reactionsDisabled: boolean,
|
reactionsDisabled: boolean,
|
||||||
|
download: (string) => void,
|
||||||
|
streamingUrl: ?string,
|
||||||
};
|
};
|
||||||
|
|
||||||
function FileActions(props: Props) {
|
function FileActions(props: Props) {
|
||||||
|
@ -45,6 +50,8 @@ function FileActions(props: Props) {
|
||||||
doToast,
|
doToast,
|
||||||
isLivestreamClaim,
|
isLivestreamClaim,
|
||||||
reactionsDisabled,
|
reactionsDisabled,
|
||||||
|
download,
|
||||||
|
streamingUrl,
|
||||||
} = props;
|
} = props;
|
||||||
const {
|
const {
|
||||||
push,
|
push,
|
||||||
|
@ -57,6 +64,8 @@ function FileActions(props: Props) {
|
||||||
const claimId = claim && claim.claim_id;
|
const claimId = claim && claim.claim_id;
|
||||||
const { signing_channel: signingChannel } = claim;
|
const { signing_channel: signingChannel } = claim;
|
||||||
const channelName = signingChannel && signingChannel.name;
|
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
|
// 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
|
// 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
|
// We will select the claim id before they publish
|
||||||
|
@ -76,6 +85,22 @@ function FileActions(props: Props) {
|
||||||
const urlParams = new URLSearchParams(search);
|
const urlParams = new URLSearchParams(search);
|
||||||
const collectionId = urlParams.get(COLLECTIONS_CONSTS.COLLECTION_ID);
|
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() {
|
function handleRepostClick() {
|
||||||
if (!hasChannels) {
|
if (!hasChannels) {
|
||||||
clearPlayingUri();
|
clearPlayingUri();
|
||||||
|
@ -114,7 +139,9 @@ function FileActions(props: Props) {
|
||||||
|
|
||||||
const rhsSection = (
|
const rhsSection = (
|
||||||
<>
|
<>
|
||||||
{!SIMPLE_SITE && <FileDownloadLink uri={uri} />}
|
{/* @if TARGET='app' */}
|
||||||
|
<FileDownloadLink uri={uri} />
|
||||||
|
{/* @endif */}
|
||||||
{claimIsMine && (
|
{claimIsMine && (
|
||||||
<Button
|
<Button
|
||||||
className="button--file-action"
|
className="button--file-action"
|
||||||
|
@ -135,14 +162,38 @@ function FileActions(props: Props) {
|
||||||
onClick={() => openModal(MODALS.CONFIRM_FILE_REMOVE, { uri })}
|
onClick={() => openModal(MODALS.CONFIRM_FILE_REMOVE, { uri })}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{!claimIsMine && (
|
<Menu>
|
||||||
<Button
|
<MenuButton
|
||||||
title={__('Report content')}
|
|
||||||
className="button--file-action"
|
className="button--file-action"
|
||||||
icon={ICONS.REPORT}
|
onClick={(e) => {
|
||||||
navigate={`/$/${PAGES.REPORT_CONTENT}?claimId=${claimId}`}
|
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>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import * as ICONS from 'constants/icons';
|
||||||
import * as MODALS from 'constants/modal_types';
|
import * as MODALS from 'constants/modal_types';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
|
import { webDownloadClaim } from 'util/downloadClaim';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
uri: string,
|
uri: string,
|
||||||
|
@ -46,16 +47,7 @@ function FileDownloadLink(props: Props) {
|
||||||
// @if TARGET='web'
|
// @if TARGET='web'
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (didClickDownloadButton && streamingUrl) {
|
if (didClickDownloadButton && streamingUrl) {
|
||||||
let element = document.createElement('a');
|
webDownloadClaim(streamingUrl, fileName);
|
||||||
element.setAttribute('href', `${streamingUrl}?download=true`);
|
|
||||||
element.setAttribute('download', fileName);
|
|
||||||
element.style.display = 'none';
|
|
||||||
// $FlowFixMe
|
|
||||||
document.body.appendChild(element);
|
|
||||||
element.click();
|
|
||||||
// $FlowFixMe
|
|
||||||
document.body.removeChild(element);
|
|
||||||
|
|
||||||
setDidClickDownloadButton(false);
|
setDidClickDownloadButton(false);
|
||||||
}
|
}
|
||||||
}, [streamingUrl, didClickDownloadButton, fileName]);
|
}, [streamingUrl, didClickDownloadButton, fileName]);
|
||||||
|
|
13
ui/util/downloadClaim.js
Normal file
13
ui/util/downloadClaim.js
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
export function webDownloadClaim(streamingUrl, fileName) {
|
||||||
|
// @if TARGET='web'
|
||||||
|
let element = document.createElement('a');
|
||||||
|
element.setAttribute('href', `${streamingUrl}?download=true`);
|
||||||
|
element.setAttribute('download', fileName);
|
||||||
|
element.style.display = 'none';
|
||||||
|
// $FlowFixMe
|
||||||
|
document.body.appendChild(element);
|
||||||
|
element.click();
|
||||||
|
// $FlowFixMe
|
||||||
|
document.body.removeChild(element);
|
||||||
|
// @endif
|
||||||
|
}
|
Loading…
Reference in a new issue