2018-03-26 23:32:43 +02:00
|
|
|
// @flow
|
|
|
|
import * as React from 'react';
|
2018-05-05 21:04:47 +02:00
|
|
|
import { Lbry, buildURI, normalizeURI, MODALS } from 'lbry-redux';
|
2017-12-21 22:08:54 +01:00
|
|
|
import Video from 'component/video';
|
2018-03-26 23:32:43 +02:00
|
|
|
import Thumbnail from 'component/common/thumbnail';
|
2017-12-21 22:08:54 +01:00
|
|
|
import FilePrice from 'component/filePrice';
|
|
|
|
import FileDetails from 'component/fileDetails';
|
2018-03-26 23:32:43 +02:00
|
|
|
import FileActions from 'component/fileActions';
|
2017-12-21 22:08:54 +01:00
|
|
|
import UriIndicator from 'component/uriIndicator';
|
2018-05-11 19:47:05 +02:00
|
|
|
import { FormField, FormRow } from 'component/common/form';
|
2018-03-26 23:32:43 +02:00
|
|
|
import Icon from 'component/common/icon';
|
2017-12-21 22:08:54 +01:00
|
|
|
import DateTime from 'component/dateTime';
|
|
|
|
import * as icons from 'constants/icons';
|
2018-03-26 23:32:43 +02:00
|
|
|
import Button from 'component/button';
|
2017-12-21 22:08:54 +01:00
|
|
|
import SubscribeButton from 'component/subscribeButton';
|
2018-03-30 18:13:11 +02:00
|
|
|
import ViewOnWebButton from 'component/viewOnWebButton';
|
2018-03-26 23:32:43 +02:00
|
|
|
import Page from 'component/page';
|
|
|
|
import player from 'render-media';
|
2018-04-30 17:27:20 +02:00
|
|
|
import * as settings from 'constants/settings';
|
2018-05-07 06:50:55 +02:00
|
|
|
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';
|
2018-06-13 22:32:38 +02:00
|
|
|
import classnames from 'classnames';
|
2017-09-12 06:24:04 +02:00
|
|
|
|
2018-03-26 23:32:43 +02:00
|
|
|
type Props = {
|
2018-05-07 06:50:55 +02:00
|
|
|
claim: Claim,
|
2018-03-26 23:32:43 +02:00
|
|
|
fileInfo: {},
|
|
|
|
metadata: {
|
|
|
|
title: string,
|
|
|
|
thumbnail: string,
|
|
|
|
nsfw: boolean,
|
|
|
|
},
|
|
|
|
contentType: string,
|
|
|
|
uri: string,
|
|
|
|
rewardedContentClaimIds: Array<string>,
|
|
|
|
obscureNsfw: boolean,
|
|
|
|
claimIsMine: boolean,
|
2018-05-11 18:36:04 +02:00
|
|
|
autoplay: boolean,
|
2018-03-26 23:32:43 +02:00
|
|
|
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,
|
2018-05-23 05:48:22 +02:00
|
|
|
prepareEdit: ({}, string) => void,
|
2018-05-11 19:47:05 +02:00
|
|
|
setClientSetting: (string, boolean | string) => void,
|
|
|
|
checkSubscription: ({ channelName: string, uri: string }) => void,
|
2018-05-21 22:30:00 +02:00
|
|
|
subscriptions: Array<Subscription>,
|
2018-03-26 23:32:43 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
class FilePage extends React.Component<Props> {
|
2018-04-30 17:27:20 +02:00
|
|
|
constructor(props: Props) {
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
(this: any).onAutoplayChange = this.onAutoplayChange.bind(this);
|
|
|
|
}
|
|
|
|
|
2017-05-13 00:50:51 +02:00
|
|
|
componentDidMount() {
|
2018-06-08 20:31:00 +02:00
|
|
|
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
|
|
|
|
2018-06-08 20:31:00 +02:00
|
|
|
// See https://github.com/lbryio/lbry-app/pull/1563 for discussion
|
2018-06-07 19:47:09 +02:00
|
|
|
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);
|
2017-05-26 20:17:01 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-11 18:36:04 +02:00
|
|
|
onAutoplayChange(event: SyntheticInputEvent<*>) {
|
|
|
|
this.props.setClientSetting(settings.AUTOPLAY, event.target.checked);
|
|
|
|
}
|
|
|
|
|
2018-04-06 08:00:36 +02:00
|
|
|
checkSubscription = (props: Props) => {
|
2018-03-30 18:13:11 +02:00
|
|
|
if (props.subscriptions.find(sub => sub.channelName === props.claim.channel_name)) {
|
2018-03-15 09:35:47 +01:00
|
|
|
props.checkSubscription({
|
|
|
|
channelName: props.claim.channel_name,
|
|
|
|
uri: buildURI(
|
|
|
|
{
|
|
|
|
contentName: props.claim.channel_name,
|
|
|
|
claimId: props.claim.value.publisherSignature.certificateId,
|
|
|
|
},
|
|
|
|
false
|
|
|
|
),
|
|
|
|
});
|
2018-03-07 21:02:53 +01:00
|
|
|
}
|
2018-04-06 08:00:36 +02:00
|
|
|
};
|
2018-03-06 09:32:58 +01:00
|
|
|
|
2017-05-12 19:14:06 +02:00
|
|
|
render() {
|
2017-07-25 09:07:54 +02:00
|
|
|
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,
|
2018-04-30 17:27:20 +02:00
|
|
|
autoplay,
|
2018-03-30 18:13:11 +02:00
|
|
|
costInfo,
|
2017-07-25 09:07:54 +02:00
|
|
|
} = this.props;
|
2017-05-01 22:50:07 +02:00
|
|
|
|
2018-03-26 23:32:43 +02:00
|
|
|
// File info
|
2018-04-06 08:00:36 +02:00
|
|
|
const { title, thumbnail } = metadata;
|
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 { height, channel_name: channelName, value } = claim;
|
2018-04-18 06:03:01 +02:00
|
|
|
const mediaType = Lbry.getMediaType(contentType);
|
2018-06-14 22:10:50 +02:00
|
|
|
const isPlayable = Object.values(player.mime).includes(contentType) || mediaType === 'audio';
|
2017-12-08 21:14:35 +01:00
|
|
|
const channelClaimId =
|
2017-12-21 22:08:54 +01:00
|
|
|
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) {
|
2018-01-19 16:12:28 +01:00
|
|
|
subscriptionUri = buildURI({ channelName, claimId: channelClaimId }, false);
|
2017-12-08 21:14:35 +01:00
|
|
|
}
|
2018-03-30 18:13:11 +02:00
|
|
|
const speechSharable =
|
|
|
|
costInfo &&
|
|
|
|
costInfo.cost === 0 &&
|
|
|
|
contentType &&
|
|
|
|
['video', 'image'].includes(contentType.split('/')[0]);
|
2017-12-08 21:14:35 +01:00
|
|
|
|
2018-05-23 06:35:34 +02: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);
|
2018-05-23 06:35:34 +02:00
|
|
|
}
|
|
|
|
|
2017-05-12 19:14:06 +02:00
|
|
|
return (
|
2018-03-26 23:32:43 +02:00
|
|
|
<Page extraPadding>
|
|
|
|
{!claim || !metadata ? (
|
|
|
|
<section>
|
|
|
|
<span className="empty">{__('Empty claim or metadata info.')}</span>
|
|
|
|
</section>
|
|
|
|
) : (
|
|
|
|
<section className="card">
|
2018-06-13 22:32:38 +02:00
|
|
|
{isPlayable && <Video className="content__embedded" uri={uri} />}
|
|
|
|
{!isPlayable &&
|
|
|
|
(thumbnail ? (
|
|
|
|
<Thumbnail shouldObscure={shouldObscureThumbnail} src={thumbnail} />
|
|
|
|
) : (
|
|
|
|
<div
|
|
|
|
className={classnames('content__empty', {
|
|
|
|
'content__empty--nsfw': shouldObscureThumbnail,
|
|
|
|
})}
|
|
|
|
>
|
2018-06-13 22:47:22 +02:00
|
|
|
<div className="card__media-text">{__('This content is not playable.')}</div>
|
2018-06-13 22:32:38 +02:00
|
|
|
</div>
|
|
|
|
))}
|
2018-03-26 23:32:43 +02:00
|
|
|
<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">
|
|
|
|
<FilePrice uri={normalizeURI(uri)} />
|
2018-05-31 04:01:19 +02:00
|
|
|
{isRewardContent && (
|
|
|
|
<Icon iconColor="red" tooltip="bottom" icon={icons.FEATURED} />
|
|
|
|
)}
|
2017-09-17 22:33:52 +02:00
|
|
|
</div>
|
2017-10-10 06:53:50 +02:00
|
|
|
</div>
|
2018-03-26 23:32:43 +02:00
|
|
|
<span className="card__subtitle card__subtitle--file">
|
|
|
|
{__('Published on')}
|
|
|
|
<DateTime block={height} show={DateTime.SHOW_DATE} />
|
|
|
|
</span>
|
|
|
|
{metadata.nsfw && <div>NSFW</div>}
|
|
|
|
<div className="card__channel-info">
|
|
|
|
<UriIndicator uri={uri} link />
|
|
|
|
<div className="card__actions card__actions--no-margin">
|
|
|
|
{claimIsMine ? (
|
|
|
|
<Button
|
|
|
|
button="primary"
|
|
|
|
icon={icons.EDIT}
|
|
|
|
label={__('Edit')}
|
|
|
|
onClick={() => {
|
2018-05-23 06:35:34 +02:00
|
|
|
prepareEdit(claim, editUri);
|
2018-03-26 23:32:43 +02:00
|
|
|
navigate('/publish');
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
) : (
|
2018-06-13 23:07:19 +02:00
|
|
|
<SubscribeButton uri={subscriptionUri} channelName={channelName} />
|
2018-03-30 18:13:11 +02:00
|
|
|
)}
|
2018-03-26 23:32:43 +02:00
|
|
|
</div>
|
|
|
|
</div>
|
2018-06-15 19:06:40 +02:00
|
|
|
{(!claimIsMine || speechSharable) && (
|
|
|
|
<div className="card__actions card__actions--end">
|
|
|
|
{!claimIsMine && (
|
|
|
|
<Button
|
|
|
|
button="alt"
|
|
|
|
icon="Send"
|
|
|
|
label={__('Enjoy this? Send a tip')}
|
|
|
|
onClick={() => openModal({ id: MODALS.SEND_TIP }, { uri })}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
{speechSharable && (
|
|
|
|
<ViewOnWebButton claimId={claim.claim_id} claimName={claim.name} />
|
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
)}
|
2018-05-11 19:47:05 +02:00
|
|
|
<FormRow alignRight>
|
2018-05-11 18:36:04 +02:00
|
|
|
<FormField
|
|
|
|
type="checkbox"
|
|
|
|
name="autoplay"
|
|
|
|
onChange={this.onAutoplayChange}
|
|
|
|
checked={autoplay}
|
|
|
|
postfix={__('Autoplay')}
|
|
|
|
/>
|
2018-05-11 19:47:05 +02:00
|
|
|
</FormRow>
|
2018-03-26 23:32:43 +02:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<div className="card__content">
|
2018-05-21 22:30:00 +02:00
|
|
|
<FileDownloadLink uri={uri} />
|
2018-05-31 04:01:19 +02:00
|
|
|
<FileActions uri={uri} claimId={claim.claim_id} />
|
2018-05-21 22:30:00 +02:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<div className="card__content--extra-padding">
|
2018-01-09 02:15:44 +01:00
|
|
|
<FileDetails uri={uri} />
|
|
|
|
</div>
|
2018-03-26 23:32:43 +02:00
|
|
|
</section>
|
|
|
|
)}
|
|
|
|
</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
|
|
|
|
2017-05-26 02:16:25 +02:00
|
|
|
export default FilePage;
|