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

198 lines
5.9 KiB
React
Raw Normal View History

2018-03-26 23:32:43 +02:00
// @flow
import * as React from 'react';
import lbry from 'lbry';
import { buildURI, normalizeURI } from 'lbryURI';
import Video from 'component/video';
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 WalletSendTip from 'component/walletSendTip';
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';
2018-03-26 23:32:43 +02:00
import Page from 'component/page';
import player from 'render-media';
import * as modals from 'constants/modal_types';
2018-03-26 23:32:43 +02:00
type Props = {
claim: {
claim_id: string,
height: number,
channel_name: string,
value: {
publisherSignature: ?{
certificateId: ?string,
},
},
},
fileInfo: {},
metadata: {
title: string,
thumbnail: string,
nsfw: boolean,
},
contentType: string,
uri: string,
rewardedContentClaimIds: Array<string>,
obscureNsfw: boolean,
playingUri: ?string,
isPaused: boolean,
claimIsMine: boolean,
costInfo: ?{},
navigate: (string, ?{}) => void,
openModal: (string, any) => void,
fetchFileInfo: string => void,
fetchCostInfo: string => void,
prepareEdit: ({}) => void,
};
class FilePage extends React.Component<Props> {
2017-05-13 00:50:51 +02:00
componentDidMount() {
2018-03-26 23:32:43 +02:00
const { uri, fileInfo, fetchFileInfo, costInfo, 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-03-26 23:32:43 +02:00
if (costInfo === undefined) {
fetchCostInfo(uri);
2017-05-12 19:14:06 +02:00
}
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);
}
}
checkSubscription(props) {
2018-03-07 21:02:53 +01:00
if (
props.subscriptions
.map(subscription => subscription.channelName)
.indexOf(props.claim.channel_name) !== -1
) {
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
}
}
2017-05-12 19:14:06 +02:00
render() {
const {
claim,
fileInfo,
metadata,
contentType,
uri,
2017-07-30 00:56:08 +02:00
rewardedContentClaimIds,
2018-03-26 23:32:43 +02:00
obscureNsfw,
playingUri,
isPaused,
openModal,
claimIsMine,
prepareEdit,
navigate,
} = this.props;
2017-05-01 22:50:07 +02:00
2018-03-26 23:32:43 +02:00
// File info
2017-06-06 23:19:12 +02:00
const title = metadata.title;
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 thumbnail = metadata.thumbnail;
const { height, channel_name: channelName, value } = claim;
2017-06-06 23:19:12 +02:00
const mediaType = lbry.getMediaType(contentType);
const isPlayable =
Object.values(player.mime).indexOf(contentType) !== -1 || mediaType === 'audio';
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
}
2018-03-26 23:32:43 +02:00
const isPlaying = playingUri === uri && !isPaused;
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">
{isPlayable ? (
<Video className="content__embedded" uri={uri} />
) : (
<Thumbnail shouldObscure={shouldObscureThumbnail} src={thumbnail} />
)}
{!isPlaying && (
<div className="card-media__internal-links">
<FileActions uri={uri} vertical />
</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">
<FilePrice uri={normalizeURI(uri)} />
{isRewardContent && <Icon 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')}&nbsp;
<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={() => {
prepareEdit(claim);
navigate('/publish');
}}
/>
) : (
<React.Fragment>
<Button
button="alt"
iconRight="Send"
label={__('Enjoy this? Send a tip')}
onClick={() => openModal(modals.SEND_TIP, { uri })}
/>
<SubscribeButton uri={subscriptionUri} channelName={channelName} />
</React.Fragment>
)}
</div>
</div>
</div>
<div className="card__content">
<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
export default FilePage;