lbry-desktop/ui/page/file/view.jsx

258 lines
8.3 KiB
React
Raw Normal View History

2018-03-26 23:32:43 +02:00
// @flow
2018-11-26 02:21:25 +01:00
import * as MODALS from 'constants/modal_types';
import * as icons from 'constants/icons';
2018-03-26 23:32:43 +02:00
import * as React from 'react';
2019-08-02 23:03:26 +02:00
import { buildURI, normalizeURI } from 'lbry-redux';
2019-08-13 07:35:13 +02:00
import FileViewerInitiator from 'component/fileViewerInitiator';
import FilePrice from 'component/filePrice';
import FileDetails from 'component/fileDetails';
2018-03-26 23:32:43 +02:00
import FileActions from 'component/fileActions';
import DateTime from 'component/dateTime';
2018-03-26 23:32:43 +02:00
import Button from 'component/button';
import Page from 'component/page';
2018-05-21 22:30:00 +02:00
import FileDownloadLink from 'component/fileDownloadLink';
import RecommendedContent from 'component/recommendedContent';
2019-11-22 22:13:00 +01:00
2019-05-17 20:21:07 +02:00
import CommentsList from 'component/commentsList';
import CommentCreate from 'component/commentCreate';
2019-07-08 20:58:33 +02:00
import ClaimUri from 'component/claimUri';
2019-07-21 23:31:22 +02:00
import ClaimPreview from 'component/claimPreview';
2019-10-03 23:40:54 +02:00
import HelpLink from 'component/common/help-link';
import I18nMessage from 'component/i18nMessage/view';
2019-08-13 07:35:13 +02:00
export const FILE_WRAPPER_CLASS = 'grid-area--content';
2018-03-26 23:32:43 +02:00
type Props = {
2019-04-24 16:02:08 +02:00
claim: StreamClaim,
fileInfo: FileListItem,
2018-03-26 23:32:43 +02:00
contentType: string,
uri: string,
claimIsMine: boolean,
costInfo: ?{ cost: number },
2018-03-26 23:32:43 +02:00
fetchFileInfo: string => void,
fetchCostInfo: string => void,
setViewed: string => void,
2018-10-19 22:38:07 +02:00
isSubscribed: ?string,
isSubscribed: boolean,
channelUri: string,
2019-03-14 19:40:26 +01:00
viewCount: number,
2019-06-11 17:30:36 +02:00
prepareEdit: ({}, string, {}) => void,
2019-08-02 23:03:26 +02:00
openModal: (id: string, { uri: string, claimIsMine?: boolean, isSupport?: boolean }) => void,
2018-10-19 22:38:07 +02:00
markSubscriptionRead: (string, string) => void,
2019-03-14 19:40:26 +01:00
fetchViewCount: string => void,
balance: number,
2019-04-24 16:02:08 +02:00
title: string,
nsfw: boolean,
supportOption: boolean,
2018-03-26 23:32:43 +02:00
};
class FilePage extends React.Component<Props> {
2017-05-13 00:50:51 +02:00
componentDidMount() {
2019-09-27 05:52:04 +02:00
const { uri, claim, fetchFileInfo, fetchCostInfo, setViewed, isSubscribed, fetchViewCount } = this.props;
2018-10-19 22:38:07 +02:00
if (isSubscribed) {
2018-10-19 22:38:07 +02:00
this.removeFromSubscriptionNotifications();
}
2019-03-14 19:40:26 +01:00
2019-09-27 05:52:04 +02:00
fetchViewCount(claim.claim_id);
2019-03-14 19:40:26 +01:00
2019-03-15 17:15:31 +01:00
// always refresh file info when entering file page to see if we have the file
// @if TARGET='app'
fetchFileInfo(uri);
2019-03-15 17:15:31 +01:00
// @endif
2017-05-12 19:14:06 +02:00
// See https://github.com/lbryio/lbry-desktop/pull/1563 for discussion
fetchCostInfo(uri);
setViewed(uri);
2017-05-12 19:14:06 +02:00
}
2018-10-19 22:38:07 +02:00
componentDidUpdate(prevProps: Props) {
2019-09-27 05:52:04 +02:00
const { isSubscribed, claim, uri, fileInfo, setViewed, fetchViewCount, fetchFileInfo } = this.props;
2019-03-14 19:40:26 +01:00
if (!prevProps.isSubscribed && isSubscribed) {
2018-10-19 22:38:07 +02:00
this.removeFromSubscriptionNotifications();
}
2019-03-14 19:40:26 +01:00
2019-09-27 05:52:04 +02:00
if (prevProps.uri !== uri) {
2019-03-14 19:40:26 +01:00
fetchViewCount(claim.claim_id);
}
2019-06-11 20:10:58 +02:00
if (prevProps.uri !== uri) {
setViewed(uri);
}
// @if TARGET='app'
if (fileInfo === undefined) {
fetchFileInfo(uri);
}
// @endif
2018-10-19 22:38:07 +02:00
}
removeFromSubscriptionNotifications() {
// Always try to remove
// If it doesn't exist, nothing will happen
const { markSubscriptionRead, uri, channelUri } = this.props;
2018-10-19 22:38:07 +02:00
markSubscriptionRead(channelUri, uri);
}
2017-05-12 19:14:06 +02:00
render() {
const {
claim,
contentType,
uri,
2018-03-26 23:32:43 +02:00
openModal,
claimIsMine,
prepareEdit,
costInfo,
fileInfo,
2018-10-19 22:38:07 +02:00
channelUri,
2019-03-14 19:40:26 +01:00
viewCount,
balance,
2019-04-24 16:02:08 +02:00
title,
nsfw,
supportOption,
} = this.props;
2018-03-26 23:32:43 +02:00
// File info
2019-06-11 20:10:58 +02:00
const { signing_channel: signingChannel } = claim;
const channelName = signingChannel && signingChannel.name;
2019-10-29 17:23:56 +01:00
const webShareable =
costInfo && costInfo.cost === 0 && contentType && ['video', 'image', 'audio'].includes(contentType.split('/')[0]);
// 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) {
2019-08-28 01:36:41 +02:00
const uriObject: { streamName: string, streamClaimId: string, channelName?: string } = {
streamName: claim.name,
streamClaimId: claim.claim_id,
2018-10-19 22:38:07 +02:00
};
if (channelName) {
2018-06-12 07:11:17 +02:00
uriObject.channelName = channelName;
}
editUri = buildURI(uriObject);
}
const insufficientCredits = !claimIsMine && costInfo && costInfo.cost > balance;
2017-05-12 19:14:06 +02:00
return (
2019-06-11 20:10:58 +02:00
<Page className="main--file-page">
2019-11-22 22:13:00 +01:00
<ClaimUri uri={uri} />
2019-08-13 07:35:13 +02:00
<div className={`card ${FILE_WRAPPER_CLASS}`}>
{!fileInfo && insufficientCredits && (
<div className="media__insufficient-credits help--warning">
<I18nMessage
tokens={{
reward_link: <Button button="link" navigate="/$/rewards" label={__('Rewards')} />,
}}
>
The publisher has chosen to charge LBC to view this content. Your balance is currently too low to view
it. Check out %reward_link% for free LBC or send more LBC to your wallet.
</I18nMessage>
</div>
)}
2019-08-13 07:35:13 +02:00
<FileViewerInitiator uri={uri} insufficientCredits={insufficientCredits} />
2019-01-09 19:39:05 +01:00
</div>
2019-11-22 22:13:00 +01:00
<div className="media__title">
<span className="media__title-price">
<FilePrice badge uri={normalizeURI(uri)} />
</span>
<h1 className="media__title-text">{title}</h1>
</div>
2019-07-09 04:41:48 +02:00
<div className="columns">
<div className="grid-area--info">
2019-11-22 22:13:00 +01:00
<div className="media__subtitle--between">
<DateTime uri={uri} show={DateTime.SHOW_DATE} />
<span>
{viewCount} {viewCount !== 1 ? __('Views') : __('View')}
<HelpLink href="https://lbry.com/faq/views" />
</span>
</div>
<div className="media__actions">
<div className="section__actions">
{claimIsMine && (
<Button
button="alt"
icon={icons.EDIT}
label={__('Edit')}
navigate="/$/publish"
onClick={() => {
prepareEdit(claim, editUri, fileInfo);
}}
/>
)}
<Button
button="alt"
icon={icons.SHARE}
label={__('Share')}
onClick={() => openModal(MODALS.SOCIAL_SHARE, { uri, webShareable })}
/>
{!claimIsMine && (
2019-07-21 23:31:22 +02:00
<Button
button="alt"
2019-11-22 22:13:00 +01:00
icon={icons.TIP}
label={__('Tip')}
requiresAuth={IS_WEB}
title={__('Send a tip to this creator')}
onClick={() => openModal(MODALS.SEND_TIP, { uri, claimIsMine, isSupport: false })}
2019-07-21 23:31:22 +02:00
/>
2019-11-22 22:13:00 +01:00
)}
{(claimIsMine || (!claimIsMine && supportOption)) && (
<Button
button="alt"
icon={icons.SUPPORT}
label={__('Support')}
requiresAuth={IS_WEB}
title={__('Support this claim')}
onClick={() => openModal(MODALS.SEND_TIP, { uri, claimIsMine, isSupport: true })}
/>
)}
</div>
<div className="section__actions">
{/* @if TARGET='app' */}
<FileDownloadLink uri={uri} />
{/* @endif */}
<FileActions uri={uri} claimId={claim.claim_id} />
2019-07-09 04:41:48 +02:00
</div>
2019-06-27 08:18:45 +02:00
</div>
2019-11-22 22:13:00 +01:00
<div className="section__divider">
<hr />
</div>
2019-07-22 04:05:37 +02:00
{channelUri ? (
2019-11-22 22:13:00 +01:00
<ClaimPreview uri={channelUri} type="inline" properties={false} hideBlock />
2019-07-22 04:05:37 +02:00
) : (
<div className="claim-preview--inline claim-preview-title">{__('Anonymous')}</div>
)}
2019-06-27 08:18:45 +02:00
2019-11-22 22:13:00 +01:00
<FileDetails uri={uri} />
<div className="section__divider">
<hr />
2019-11-14 21:02:15 +01:00
</div>
2019-11-22 22:13:00 +01:00
<div className="section__title--small">{__('Comments')}</div>
2019-11-14 21:02:15 +01:00
<section className="section">
2019-07-09 04:41:48 +02:00
<CommentCreate uri={uri} />
2019-11-14 21:02:15 +01:00
</section>
<section className="section">
2019-07-09 04:41:48 +02:00
<CommentsList uri={uri} />
2019-11-14 21:02:15 +01:00
</section>
</div>
2019-07-09 04:41:48 +02:00
<div className="grid-area--related">
2019-11-22 22:13:00 +01:00
{nsfw && <div className="badge badge--mature">{__('Mature')}</div>}
2019-07-09 04:41:48 +02:00
<RecommendedContent uri={uri} />
2019-06-17 22:32:38 +02:00
</div>
2019-01-09 19:39:05 +01:00
</div>
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;