lbry-desktop/src/renderer/page/file/view.jsx

251 lines
8.2 KiB
React
Raw Normal View History

2018-03-26 23:32:43 +02:00
// @flow
import * as React from 'react';
import * as settings from 'constants/settings';
2018-07-10 04:57:34 +02:00
import { buildURI, normalizeURI, MODALS } from 'lbry-redux';
2018-07-10 05:32:59 +02:00
import FileViewer from 'component/fileViewer';
2018-03-26 23:32:43 +02:00
import Thumbnail from 'component/common/thumbnail';
import FilePrice from 'component/filePrice';
import FileDetails from 'component/fileDetails';
2018-03-26 23:32:43 +02:00
import FileActions from 'component/fileActions';
import UriIndicator from 'component/uriIndicator';
2018-03-26 23:32:43 +02:00
import Icon from 'component/common/icon';
import DateTime from 'component/dateTime';
import * as icons from 'constants/icons';
2018-03-26 23:32:43 +02:00
import Button from 'component/button';
import SubscribeButton from 'component/subscribeButton';
import ViewOnWebButton from 'component/viewOnWebButton';
2018-03-26 23:32:43 +02:00
import Page from 'component/page';
import type { Claim } from 'types/claim';
2018-05-21 22:30:00 +02:00
import type { Subscription } from 'types/subscription';
import FileDownloadLink from 'component/fileDownloadLink';
import classnames from 'classnames';
2018-07-10 04:57:34 +02:00
import getMediaType from 'util/getMediaType';
import RecommendedContent from 'component/recommendedContent';
import { FormField, FormRow } from 'component/common/form';
import ToolTip from 'component/common/tooltip';
2018-03-26 23:32:43 +02:00
type Props = {
claim: Claim,
2018-03-26 23:32:43 +02:00
fileInfo: {},
metadata: {
title: string,
thumbnail: string,
file_name: string,
2018-03-26 23:32:43 +02:00
nsfw: boolean,
},
contentType: string,
uri: string,
rewardedContentClaimIds: Array<string>,
obscureNsfw: boolean,
claimIsMine: boolean,
costInfo: ?{},
navigate: (string, ?{}) => void,
2018-04-19 18:51:18 +02:00
openModal: ({ id: string }, { uri: string }) => void,
2018-03-26 23:32:43 +02:00
fetchFileInfo: string => void,
fetchCostInfo: string => void,
prepareEdit: ({}, string) => void,
checkSubscription: (uri: string) => void,
2018-05-21 22:30:00 +02:00
subscriptions: Array<Subscription>,
setClientSetting: (string, boolean | string) => void,
autoplay: boolean,
2018-03-26 23:32:43 +02:00
};
class FilePage extends React.Component<Props> {
static PLAYABLE_MEDIA_TYPES = ['audio', 'video'];
static PREVIEW_MEDIA_TYPES = [
'text',
'model',
'image',
'script',
'document',
'3D-file',
// Bypass unplayable files
// TODO: Find a better way to detect supported types
'application',
];
2018-06-11 08:41:25 +02:00
constructor(props: Props) {
super(props);
(this: any).onAutoplayChange = this.onAutoplayChange.bind(this);
}
2017-05-13 00:50:51 +02:00
componentDidMount() {
const { uri, fileInfo, fetchFileInfo, fetchCostInfo } = this.props;
2017-05-12 19:14:06 +02:00
2018-03-26 23:32:43 +02:00
if (fileInfo === undefined) {
fetchFileInfo(uri);
}
2017-05-12 19:14:06 +02:00
// See https://github.com/lbryio/lbry-desktop/pull/1563 for discussion
fetchCostInfo(uri);
2018-03-26 23:32:43 +02:00
this.checkSubscription(this.props);
2017-05-12 19:14:06 +02:00
}
2018-03-26 23:32:43 +02:00
componentWillReceiveProps(nextProps: Props) {
const { fetchFileInfo, uri } = this.props;
if (nextProps.fileInfo === undefined) {
fetchFileInfo(uri);
}
}
onAutoplayChange(event: SyntheticInputEvent<*>) {
this.props.setClientSetting(settings.AUTOPLAY, event.target.checked);
}
checkSubscription = (props: Props) => {
if (props.subscriptions.find(sub => sub.channelName === props.claim.channel_name)) {
props.checkSubscription(
buildURI({
contentName: props.claim.channel_name,
claimId: props.claim.value.publisherSignature.certificateId,
}, false)
);
2018-03-07 21:02:53 +01:00
}
};
2017-05-12 19:14:06 +02:00
render() {
const {
claim,
metadata,
contentType,
uri,
2017-07-30 00:56:08 +02:00
rewardedContentClaimIds,
2018-03-26 23:32:43 +02:00
obscureNsfw,
openModal,
claimIsMine,
prepareEdit,
navigate,
costInfo,
fileInfo,
autoplay,
} = this.props;
2017-05-01 22:50:07 +02:00
2018-03-26 23:32:43 +02:00
// File info
const { title, thumbnail } = metadata;
const { height, channel_name: channelName, value } = claim;
const { PLAYABLE_MEDIA_TYPES, PREVIEW_MEDIA_TYPES } = FilePage;
2017-07-30 00:56:08 +02:00
const isRewardContent = rewardedContentClaimIds.includes(claim.claim_id);
2018-03-26 23:32:43 +02:00
const shouldObscureThumbnail = obscureNsfw && metadata.nsfw;
const fileName = fileInfo ? fileInfo.file_name : null;
2018-07-10 04:57:34 +02:00
const mediaType = getMediaType(contentType, fileName);
const showFile =
PLAYABLE_MEDIA_TYPES.includes(mediaType) || PREVIEW_MEDIA_TYPES.includes(mediaType);
2017-12-08 21:14:35 +01:00
const channelClaimId =
value && value.publisherSignature && value.publisherSignature.certificateId;
2017-12-08 21:14:35 +01:00
let subscriptionUri;
2017-12-08 21:38:20 +01:00
if (channelName && channelClaimId) {
subscriptionUri = buildURI({ channelName, claimId: channelClaimId }, false);
2017-12-08 21:14:35 +01:00
}
const speechSharable =
costInfo &&
costInfo.cost === 0 &&
contentType &&
['video', 'image'].includes(contentType.split('/')[0]);
2017-12-08 21:14:35 +01:00
// 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) {
2018-06-12 07:11:17 +02:00
const uriObject = { contentName: claim.name, claimId: claim.claim_id };
if (channelName) {
uriObject.channelName = channelName;
}
editUri = buildURI(uriObject);
}
2017-05-12 19:14:06 +02:00
return (
<Page forContent>
<section className="content__wrapper">
{showFile && <FileViewer className="content__embedded" uri={uri} mediaType={mediaType} />}
{!showFile &&
(thumbnail ? (
<Thumbnail shouldObscure={shouldObscureThumbnail} src={thumbnail} />
) : (
<div
className={classnames('content__empty', {
'content__empty--nsfw': shouldObscureThumbnail,
})}
>
<div className="card__media-text">
{__("Sorry, looks like we can't preview this file.")}
2017-09-17 22:33:52 +02:00
</div>
2017-10-10 06:53:50 +02:00
</div>
))}
<div className="card__content">
<div className="card__title-identity--file">
<h1 className="card__title card__title--file">{title}</h1>
<div className="card__title-identity-icons">
{isRewardContent && <Icon iconColor="red" tooltip="bottom" icon={icons.FEATURED} />}
<FilePrice filePage uri={normalizeURI(uri)} />
</div>
</div>
<span className="card__subtitle card__subtitle--file">
{__('Published on')}&nbsp;
<DateTime block={height} show={DateTime.SHOW_DATE} />
</span>
{metadata.nsfw && <div>NSFW</div>}
<div className="card__channel-info">
<UriIndicator uri={uri} link />
</div>
<div className="card__actions card__actions--no-margin card__actions--between">
<div className="card__actions">
{claimIsMine ? (
<Button
button="primary"
icon={icons.EDIT}
label={__('Edit')}
onClick={() => {
prepareEdit(claim, editUri);
navigate('/publish');
}}
/>
) : (
<SubscribeButton uri={subscriptionUri} channelName={channelName} />
)}
{!claimIsMine && (
<Button
button="alt"
icon={icons.GIFT}
2018-07-25 20:21:41 +02:00
label={__('Send a tip')}
onClick={() => openModal({ id: MODALS.SEND_TIP }, { uri })}
/>
)}
{speechSharable && (
<ViewOnWebButton claimId={claim.claim_id} claimName={claim.name} />
)}
2018-03-26 23:32:43 +02:00
</div>
2018-06-20 05:55:25 +02:00
<div className="card__actions">
<FileDownloadLink uri={uri} />
<FileActions uri={uri} claimId={claim.claim_id} />
2018-06-20 05:55:25 +02:00
</div>
2018-03-26 23:32:43 +02:00
</div>
<FormRow padded>
<ToolTip direction="right" body={__('Automatically download and play free content.')}>
<FormField
name="autoplay"
type="checkbox"
postfix={__('Autoplay')}
checked={autoplay}
onChange={this.onAutoplayChange}
/>
</ToolTip>
</FormRow>
2018-05-21 22:30:00 +02:00
<div className="card__content--extra-padding">
<FileDetails uri={uri} />
</div>
</div>
</section>
2018-08-03 20:28:11 +02:00
<RecommendedContent uri={uri} />
2018-03-26 23:32:43 +02:00
</Page>
2017-06-06 23:19:12 +02:00
);
2017-05-12 19:14:06 +02:00
}
2017-05-05 07:10:37 +02:00
}
2017-05-01 21:59:40 +02:00
export default FilePage;