mirror of
https://github.com/LBRYFoundation/lbry-desktop.git
synced 2025-08-23 17:47:24 +00:00
better posts styling
This commit is contained in:
parent
4e9a4f41c8
commit
7702477e71
23 changed files with 342 additions and 159 deletions
|
@ -254,7 +254,6 @@ export default function GetHomePageRowData(
|
||||||
rowData.push(YOUTUBE_CREATOR_ROW);
|
rowData.push(YOUTUBE_CREATOR_ROW);
|
||||||
}
|
}
|
||||||
|
|
||||||
// rowData.push(TRENDING_CLASSICS);
|
|
||||||
rowData.push(TOP_CONTENT_TODAY);
|
rowData.push(TOP_CONTENT_TODAY);
|
||||||
|
|
||||||
// rowData.push(TRENDING_ON_LBRY);
|
// rowData.push(TRENDING_ON_LBRY);
|
||||||
|
|
|
@ -899,7 +899,6 @@
|
||||||
"Already have an account? %sign_in%": "Already have an account? %sign_in%",
|
"Already have an account? %sign_in%": "Already have an account? %sign_in%",
|
||||||
"Sign in with a password (optional)": "Sign in with a password (optional)",
|
"Sign in with a password (optional)": "Sign in with a password (optional)",
|
||||||
"Don't have an account? %sign_up%": "Don't have an account? %sign_up%",
|
"Don't have an account? %sign_up%": "Don't have an account? %sign_up%",
|
||||||
"Preparing your content": "Preparing your content",
|
|
||||||
"File details": "File details",
|
"File details": "File details",
|
||||||
"You can unlock all or some of these LBRY Credits at any time.": "You can unlock all or some of these LBRY Credits at any time.",
|
"You can unlock all or some of these LBRY Credits at any time.": "You can unlock all or some of these LBRY Credits at any time.",
|
||||||
"Keeping it locked improves the trust and discoverability of your content.": "Keeping it locked improves the trust and discoverability of your content.",
|
"Keeping it locked improves the trust and discoverability of your content.": "Keeping it locked improves the trust and discoverability of your content.",
|
||||||
|
|
|
@ -53,7 +53,7 @@ export default function ClaimTags(props: Props) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classnames('file-properties--small', { 'file-properties--large': type === 'large' })}>
|
<div className={classnames('file-properties--small', { 'file-properties--large': type === 'large' })}>
|
||||||
{tagsToDisplay.map(tag => (
|
{tagsToDisplay.map((tag) => (
|
||||||
<Tag key={tag} title={tag} name={tag} />
|
<Tag key={tag} title={tag} name={tag} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,13 +4,14 @@ import ClaimPreview from 'component/claimPreview';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
channelUri: string,
|
channelUri: string,
|
||||||
|
hideActions?: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
function FileAuthor(props: Props) {
|
function FileAuthor(props: Props) {
|
||||||
const { channelUri } = props;
|
const { channelUri, hideActions } = props;
|
||||||
|
|
||||||
return channelUri ? (
|
return channelUri ? (
|
||||||
<ClaimPreview uri={channelUri} type="inline" properties={false} hideMenu />
|
<ClaimPreview uri={channelUri} type="inline" properties={false} hideMenu hideActions={hideActions} />
|
||||||
) : (
|
) : (
|
||||||
<div className="claim-preview--inline claim-preview__title">{__('Anonymous')}</div>
|
<div className="claim-preview--inline claim-preview__title">{__('Anonymous')}</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -14,12 +14,12 @@ import Nag from 'component/common/nag';
|
||||||
const SPACE_BAR_KEYCODE = 32;
|
const SPACE_BAR_KEYCODE = 32;
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
play: string => void,
|
play: (string) => void,
|
||||||
isLoading: boolean,
|
isLoading: boolean,
|
||||||
isPlaying: boolean,
|
isPlaying: boolean,
|
||||||
fileInfo: FileListItem,
|
fileInfo: FileListItem,
|
||||||
uri: string,
|
uri: string,
|
||||||
history: { push: string => void },
|
history: { push: (string) => void },
|
||||||
location: { search: ?string, pathname: string },
|
location: { search: ?string, pathname: string },
|
||||||
obscurePreview: boolean,
|
obscurePreview: boolean,
|
||||||
insufficientCredits: boolean,
|
insufficientCredits: boolean,
|
||||||
|
@ -58,6 +58,7 @@ export default function FileRenderInitiator(props: Props) {
|
||||||
const isFree = hasCostInfo && cost === 0;
|
const isFree = hasCostInfo && cost === 0;
|
||||||
const fileStatus = fileInfo && fileInfo.status;
|
const fileStatus = fileInfo && fileInfo.status;
|
||||||
const isPlayable = RENDER_MODES.FLOATING_MODES.includes(renderMode);
|
const isPlayable = RENDER_MODES.FLOATING_MODES.includes(renderMode);
|
||||||
|
const isText = RENDER_MODES.TEXT_MODES.includes(renderMode);
|
||||||
|
|
||||||
function doAuthRedirect() {
|
function doAuthRedirect() {
|
||||||
history.push(`/$/${PAGES.AUTH}?redirect=${encodeURIComponent(location.pathname)}`);
|
history.push(`/$/${PAGES.AUTH}?redirect=${encodeURIComponent(location.pathname)}`);
|
||||||
|
@ -121,6 +122,7 @@ export default function FileRenderInitiator(props: Props) {
|
||||||
className={classnames('content__cover', {
|
className={classnames('content__cover', {
|
||||||
'content__cover--disabled': disabled,
|
'content__cover--disabled': disabled,
|
||||||
'content__cover--theater-mode': videoTheaterMode,
|
'content__cover--theater-mode': videoTheaterMode,
|
||||||
|
'content__cover--text': isText,
|
||||||
'card__media--nsfw': obscurePreview,
|
'card__media--nsfw': obscurePreview,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
|
|
|
@ -52,5 +52,5 @@ export default function FileRenderInline(props: Props) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return renderContent ? <FileRender uri={uri} /> : <LoadingScreen status={__('Preparing your content')} isDocument />;
|
return renderContent ? <FileRender uri={uri} /> : <LoadingScreen isDocument />;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { makeSelectTitleForUri } from 'lbry-redux';
|
import { makeSelectTitleForUri } from 'lbry-redux';
|
||||||
import { makeSelectInsufficientCreditsForUri } from 'redux/selectors/content';
|
import FileTitleSection from './view';
|
||||||
import FileTitle from './view';
|
|
||||||
|
|
||||||
const select = (state, props) => ({
|
const select = (state, props) => ({
|
||||||
isInsufficientCredits: makeSelectInsufficientCreditsForUri(props.uri)(state),
|
|
||||||
title: makeSelectTitleForUri(props.uri)(state),
|
title: makeSelectTitleForUri(props.uri)(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select)(FileTitle);
|
export default connect(select)(FileTitleSection);
|
||||||
|
|
|
@ -1,76 +1,22 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
import type { Node } from 'react';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { normalizeURI } from 'lbry-redux';
|
import classnames from 'classnames';
|
||||||
import FilePrice from 'component/filePrice';
|
|
||||||
import ClaimInsufficientCredits from 'component/claimInsufficientCredits';
|
|
||||||
import FileSubtitle from 'component/fileSubtitle';
|
|
||||||
import FileAuthor from 'component/fileAuthor';
|
|
||||||
import Card from 'component/common/card';
|
|
||||||
import * as ICONS from 'constants/icons';
|
|
||||||
import Icon from 'component/common/icon';
|
|
||||||
import I18nMessage from 'component/i18nMessage';
|
|
||||||
import Button from 'component/button';
|
|
||||||
import * as PAGES from 'constants/pages';
|
|
||||||
import FileDescription from 'component/fileDescription';
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
uri: string,
|
|
||||||
title: string,
|
title: string,
|
||||||
nsfw: boolean,
|
className?: string,
|
||||||
isNsfwBlocked: boolean,
|
children?: Node,
|
||||||
};
|
};
|
||||||
|
|
||||||
function FileTitle(props: Props) {
|
function FileTitle(props: Props) {
|
||||||
const { title, uri, nsfw, isNsfwBlocked } = props;
|
const { title, children, className } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<h1 className={classnames(className)}>
|
||||||
isPageTitle
|
<span>{title}</span>
|
||||||
noTitleWrap
|
{children}
|
||||||
title={
|
</h1>
|
||||||
<React.Fragment>
|
|
||||||
{title}
|
|
||||||
{nsfw && (
|
|
||||||
<span className="media__title-badge">
|
|
||||||
<span className="badge badge--tag-mature">{__('Mature')}</span>
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</React.Fragment>
|
|
||||||
}
|
|
||||||
titleActions={<FilePrice uri={normalizeURI(uri)} type="filepage" />}
|
|
||||||
body={
|
|
||||||
<React.Fragment>
|
|
||||||
<ClaimInsufficientCredits uri={uri} />
|
|
||||||
<FileSubtitle uri={uri} />
|
|
||||||
</React.Fragment>
|
|
||||||
}
|
|
||||||
actions={
|
|
||||||
isNsfwBlocked ? (
|
|
||||||
<div className="main--empty">
|
|
||||||
<h2>
|
|
||||||
<Icon className="icon--hidden" icon={ICONS.EYE_OFF} />
|
|
||||||
{__('Mature content blocked.')}
|
|
||||||
</h2>
|
|
||||||
<div>
|
|
||||||
<I18nMessage
|
|
||||||
tokens={{
|
|
||||||
content_settings: (
|
|
||||||
<Button button="link" label={__('content settings')} navigate={`/$/${PAGES.SETTINGS}`} />
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Change this in your %content_settings%.
|
|
||||||
</I18nMessage>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="section">
|
|
||||||
<FileAuthor uri={uri} />
|
|
||||||
<FileDescription uri={uri} />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
ui/component/fileTitleSection/index.js
Normal file
11
ui/component/fileTitleSection/index.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { makeSelectTitleForUri } from 'lbry-redux';
|
||||||
|
import { makeSelectInsufficientCreditsForUri } from 'redux/selectors/content';
|
||||||
|
import FileTitleSection from './view';
|
||||||
|
|
||||||
|
const select = (state, props) => ({
|
||||||
|
isInsufficientCredits: makeSelectInsufficientCreditsForUri(props.uri)(state),
|
||||||
|
title: makeSelectTitleForUri(props.uri)(state),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(select)(FileTitleSection);
|
77
ui/component/fileTitleSection/view.jsx
Normal file
77
ui/component/fileTitleSection/view.jsx
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
// @flow
|
||||||
|
import * as React from 'react';
|
||||||
|
import { normalizeURI } from 'lbry-redux';
|
||||||
|
import FilePrice from 'component/filePrice';
|
||||||
|
import ClaimInsufficientCredits from 'component/claimInsufficientCredits';
|
||||||
|
import FileSubtitle from 'component/fileSubtitle';
|
||||||
|
import FileAuthor from 'component/fileAuthor';
|
||||||
|
import Card from 'component/common/card';
|
||||||
|
import * as ICONS from 'constants/icons';
|
||||||
|
import Icon from 'component/common/icon';
|
||||||
|
import I18nMessage from 'component/i18nMessage';
|
||||||
|
import Button from 'component/button';
|
||||||
|
import * as PAGES from 'constants/pages';
|
||||||
|
import FileDescription from 'component/fileDescription';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
uri: string,
|
||||||
|
title: string,
|
||||||
|
nsfw: boolean,
|
||||||
|
isNsfwBlocked: boolean,
|
||||||
|
};
|
||||||
|
|
||||||
|
function FileTitleSection(props: Props) {
|
||||||
|
const { title, uri, nsfw, isNsfwBlocked } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card
|
||||||
|
isPageTitle
|
||||||
|
noTitleWrap
|
||||||
|
title={
|
||||||
|
<React.Fragment>
|
||||||
|
{title}
|
||||||
|
{nsfw && (
|
||||||
|
<span className="media__title-badge">
|
||||||
|
<span className="badge badge--tag-mature">{__('Mature')}</span>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
|
}
|
||||||
|
titleActions={<FilePrice uri={normalizeURI(uri)} type="filepage" />}
|
||||||
|
body={
|
||||||
|
<React.Fragment>
|
||||||
|
<ClaimInsufficientCredits uri={uri} />
|
||||||
|
<FileSubtitle uri={uri} />
|
||||||
|
</React.Fragment>
|
||||||
|
}
|
||||||
|
actions={
|
||||||
|
isNsfwBlocked ? (
|
||||||
|
<div className="main--empty">
|
||||||
|
<h2>
|
||||||
|
<Icon className="icon--hidden" icon={ICONS.EYE_OFF} />
|
||||||
|
{__('Mature content blocked.')}
|
||||||
|
</h2>
|
||||||
|
<div>
|
||||||
|
<I18nMessage
|
||||||
|
tokens={{
|
||||||
|
content_settings: (
|
||||||
|
<Button button="link" label={__('content settings')} navigate={`/$/${PAGES.SETTINGS}`} />
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Change this in your %content_settings%.
|
||||||
|
</I18nMessage>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="section">
|
||||||
|
<FileAuthor uri={uri} />
|
||||||
|
<FileDescription uri={uri} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FileTitleSection;
|
|
@ -27,6 +27,7 @@ type Props = {
|
||||||
noSideNavigation: boolean,
|
noSideNavigation: boolean,
|
||||||
fullWidthPage: boolean,
|
fullWidthPage: boolean,
|
||||||
videoTheaterMode: boolean,
|
videoTheaterMode: boolean,
|
||||||
|
isText?: boolean,
|
||||||
backout: {
|
backout: {
|
||||||
backLabel?: string,
|
backLabel?: string,
|
||||||
backNavDefault?: string,
|
backNavDefault?: string,
|
||||||
|
@ -47,6 +48,7 @@ function Page(props: Props) {
|
||||||
noSideNavigation = false,
|
noSideNavigation = false,
|
||||||
backout,
|
backout,
|
||||||
videoTheaterMode,
|
videoTheaterMode,
|
||||||
|
isText = false,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -105,6 +107,7 @@ function Page(props: Props) {
|
||||||
'main--auth-page': authPage,
|
'main--auth-page': authPage,
|
||||||
'main--file-page': filePage,
|
'main--file-page': filePage,
|
||||||
'main--theater-mode': isOnFilePage && videoTheaterMode,
|
'main--theater-mode': isOnFilePage && videoTheaterMode,
|
||||||
|
'main--text': isText,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
9
ui/component/postViewer/index.js
Normal file
9
ui/component/postViewer/index.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { makeSelectClaimForUri } from 'lbry-redux';
|
||||||
|
import PostViewer from './view';
|
||||||
|
|
||||||
|
const select = (state, props) => ({
|
||||||
|
claim: makeSelectClaimForUri(props.uri)(state),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(select)(PostViewer);
|
49
ui/component/postViewer/view.jsx
Normal file
49
ui/component/postViewer/view.jsx
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
// @flow
|
||||||
|
import * as React from 'react';
|
||||||
|
import FileAuthor from 'component/fileAuthor';
|
||||||
|
import FileTitle from 'component/fileTitle';
|
||||||
|
import FileActions from 'component/fileActions';
|
||||||
|
import FileRenderInitiator from 'component/fileRenderInitiator';
|
||||||
|
import FileRenderInline from 'component/fileRenderInline';
|
||||||
|
import FileViewCount from 'component/fileViewCount';
|
||||||
|
import { formatCredits } from 'lbry-redux';
|
||||||
|
import CreditAmount from 'component/common/credit-amount';
|
||||||
|
import DateTime from 'component/dateTime';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
uri: string,
|
||||||
|
claim: ?StreamClaim,
|
||||||
|
};
|
||||||
|
|
||||||
|
function PostViewer(props: Props) {
|
||||||
|
const { uri, claim } = props;
|
||||||
|
|
||||||
|
if (!claim) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const amount = parseFloat(claim.amount) + parseFloat(claim.meta.support_amount);
|
||||||
|
const formattedAmount = formatCredits(amount, 2, true);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="post">
|
||||||
|
<FileTitle uri={uri} className="post__title">
|
||||||
|
<span className="post__date">
|
||||||
|
<DateTime uri={uri} show={DateTime.SHOW_DATE} />
|
||||||
|
</span>
|
||||||
|
</FileTitle>
|
||||||
|
<div className="post__info">
|
||||||
|
<CreditAmount amount={formattedAmount} />
|
||||||
|
<FileViewCount uri={uri} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<FileAuthor uri={uri} />
|
||||||
|
|
||||||
|
<FileRenderInitiator uri={uri} />
|
||||||
|
<FileRenderInline uri={uri} />
|
||||||
|
<FileActions uri={uri} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PostViewer;
|
|
@ -3,7 +3,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import LoadingScreen from 'component/common/loading-screen';
|
import LoadingScreen from 'component/common/loading-screen';
|
||||||
import MarkdownPreview from 'component/common/markdown-preview';
|
import MarkdownPreview from 'component/common/markdown-preview';
|
||||||
import Card from 'component/common/card';
|
|
||||||
import CodeViewer from 'component/viewers/codeViewer';
|
import CodeViewer from 'component/viewers/codeViewer';
|
||||||
import * as RENDER_MODES from 'constants/file_render_modes';
|
import * as RENDER_MODES from 'constants/file_render_modes';
|
||||||
import * as https from 'https';
|
import * as https from 'https';
|
||||||
|
@ -42,7 +41,7 @@ class DocumentViewer extends React.PureComponent<Props, State> {
|
||||||
|
|
||||||
let data = '';
|
let data = '';
|
||||||
|
|
||||||
stream.on('data', chunk => {
|
stream.on('data', (chunk) => {
|
||||||
data += chunk;
|
data += chunk;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -57,25 +56,19 @@ class DocumentViewer extends React.PureComponent<Props, State> {
|
||||||
// @endif
|
// @endif
|
||||||
// @if TARGET='web'
|
// @if TARGET='web'
|
||||||
if (source && source.stream) {
|
if (source && source.stream) {
|
||||||
https.get(
|
https.get(source.stream, (response) => {
|
||||||
source.stream,
|
if (response.statusCode === 200) {
|
||||||
function(response) {
|
let data = '';
|
||||||
if (response.statusCode === 200) {
|
response.on('data', (chunk) => {
|
||||||
let data = '';
|
data += chunk;
|
||||||
response.on('data', function(chunk) {
|
});
|
||||||
data += chunk;
|
response.on('end', () => {
|
||||||
});
|
this.setState({ content: data, loading: false });
|
||||||
response.on(
|
});
|
||||||
'end',
|
} else {
|
||||||
function() {
|
this.setState({ error: true, loading: false });
|
||||||
this.setState({ content: data, loading: false });
|
}
|
||||||
}.bind(this)
|
});
|
||||||
);
|
|
||||||
} else {
|
|
||||||
this.setState({ error: true, loading: false });
|
|
||||||
}
|
|
||||||
}.bind(this)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
// @endif
|
// @endif
|
||||||
}
|
}
|
||||||
|
@ -86,7 +79,7 @@ class DocumentViewer extends React.PureComponent<Props, State> {
|
||||||
const { contentType } = source;
|
const { contentType } = source;
|
||||||
|
|
||||||
return renderMode === RENDER_MODES.MARKDOWN ? (
|
return renderMode === RENDER_MODES.MARKDOWN ? (
|
||||||
<Card body={<MarkdownPreview content={content} isMarkdownPost promptLinks />} />
|
<MarkdownPreview content={content} isMarkdownPost promptLinks />
|
||||||
) : (
|
) : (
|
||||||
<CodeViewer value={content} contentType={contentType} theme={theme} />
|
<CodeViewer value={content} contentType={contentType} theme={theme} />
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,12 +3,13 @@ import * as React from 'react';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import Page from 'component/page';
|
import Page from 'component/page';
|
||||||
import * as RENDER_MODES from 'constants/file_render_modes';
|
import * as RENDER_MODES from 'constants/file_render_modes';
|
||||||
import FileTitle from 'component/fileTitle';
|
import FileTitleSection from 'component/fileTitleSection';
|
||||||
import FileRenderInitiator from 'component/fileRenderInitiator';
|
import FileRenderInitiator from 'component/fileRenderInitiator';
|
||||||
import FileRenderInline from 'component/fileRenderInline';
|
import FileRenderInline from 'component/fileRenderInline';
|
||||||
import FileRenderDownload from 'component/fileRenderDownload';
|
import FileRenderDownload from 'component/fileRenderDownload';
|
||||||
import RecommendedContent from 'component/recommendedContent';
|
import RecommendedContent from 'component/recommendedContent';
|
||||||
import CommentsList from 'component/commentsList';
|
import CommentsList from 'component/commentsList';
|
||||||
|
import PostViewer from 'component/postViewer';
|
||||||
import Empty from 'component/common/empty';
|
import Empty from 'component/common/empty';
|
||||||
|
|
||||||
export const PRIMARY_PLAYER_WRAPPER_CLASS = 'file-page__video-container';
|
export const PRIMARY_PLAYER_WRAPPER_CLASS = 'file-page__video-container';
|
||||||
|
@ -17,9 +18,9 @@ type Props = {
|
||||||
costInfo: ?{ includesData: boolean, cost: number },
|
costInfo: ?{ includesData: boolean, cost: number },
|
||||||
fileInfo: FileListItem,
|
fileInfo: FileListItem,
|
||||||
uri: string,
|
uri: string,
|
||||||
fetchFileInfo: string => void,
|
fetchFileInfo: (string) => void,
|
||||||
fetchCostInfo: string => void,
|
fetchCostInfo: (string) => void,
|
||||||
setViewed: string => void,
|
setViewed: (string) => void,
|
||||||
renderMode: string,
|
renderMode: string,
|
||||||
obscureNsfw: boolean,
|
obscureNsfw: boolean,
|
||||||
isMature: boolean,
|
isMature: boolean,
|
||||||
|
@ -47,6 +48,7 @@ function FilePage(props: Props) {
|
||||||
} = props;
|
} = props;
|
||||||
const cost = costInfo ? costInfo.cost : null;
|
const cost = costInfo ? costInfo.cost : null;
|
||||||
const hasFileInfo = fileInfo !== undefined;
|
const hasFileInfo = fileInfo !== undefined;
|
||||||
|
const isText = RENDER_MODES.TEXT_MODES.includes(renderMode);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
// always refresh file info when entering file page to see if we have the file
|
// always refresh file info when entering file page to see if we have the file
|
||||||
|
@ -82,27 +84,21 @@ function FilePage(props: Props) {
|
||||||
if (RENDER_MODES.UNRENDERABLE_MODES.includes(renderMode)) {
|
if (RENDER_MODES.UNRENDERABLE_MODES.includes(renderMode)) {
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<FileTitle uri={uri} />
|
<FileTitleSection uri={uri} />
|
||||||
<FileRenderDownload uri={uri} isFree={cost === 0} />
|
<FileRenderDownload uri={uri} isFree={cost === 0} />
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RENDER_MODES.TEXT_MODES.includes(renderMode)) {
|
if (RENDER_MODES.TEXT_MODES.includes(renderMode)) {
|
||||||
return (
|
return <PostViewer uri={uri} />;
|
||||||
<React.Fragment>
|
|
||||||
<FileTitle uri={uri} />
|
|
||||||
<FileRenderInitiator uri={uri} />
|
|
||||||
<FileRenderInline uri={uri} />
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<FileRenderInitiator uri={uri} videoTheaterMode={videoTheaterMode} />
|
<FileRenderInitiator uri={uri} videoTheaterMode={videoTheaterMode} />
|
||||||
<FileRenderInline uri={uri} />
|
<FileRenderInline uri={uri} />
|
||||||
<FileTitle uri={uri} />
|
<FileTitleSection uri={uri} />
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -110,27 +106,38 @@ function FilePage(props: Props) {
|
||||||
if (obscureNsfw && isMature) {
|
if (obscureNsfw && isMature) {
|
||||||
return (
|
return (
|
||||||
<Page>
|
<Page>
|
||||||
<FileTitle uri={uri} isNsfwBlocked />
|
<FileTitleSection uri={uri} isNsfwBlocked />
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page className="file-page" filePage>
|
<Page className="file-page" filePage isText={isText}>
|
||||||
<div className={classnames('section card-stack', `file-page__${renderMode}`)}>
|
<div
|
||||||
|
className={classnames('section card-stack', `file-page__${renderMode}`, {
|
||||||
|
'file-page__text': isText,
|
||||||
|
})}
|
||||||
|
>
|
||||||
{renderFilePageLayout()}
|
{renderFilePageLayout()}
|
||||||
|
|
||||||
<div className="file-page__secondary-content">
|
{!isText && (
|
||||||
<div>
|
<div className="file-page__secondary-content">
|
||||||
{RENDER_MODES.FLOATING_MODES.includes(renderMode) && <FileTitle uri={uri} />}
|
<div>
|
||||||
{commentsDisabled && <Empty text={__('The creator of this content has disabled comments.')} />}
|
{RENDER_MODES.FLOATING_MODES.includes(renderMode) && <FileTitleSection uri={uri} />}
|
||||||
{!commentsDisabled && <CommentsList uri={uri} linkedComment={linkedComment} />}
|
{commentsDisabled && <Empty text={__('The creator of this content has disabled comments.')} />}
|
||||||
|
{!commentsDisabled && <CommentsList uri={uri} linkedComment={linkedComment} />}
|
||||||
|
</div>
|
||||||
|
{videoTheaterMode && <RecommendedContent uri={uri} />}
|
||||||
</div>
|
</div>
|
||||||
{videoTheaterMode && <RecommendedContent uri={uri} />}
|
)}
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!videoTheaterMode && <RecommendedContent uri={uri} />}
|
{!isText && !videoTheaterMode && <RecommendedContent uri={uri} />}
|
||||||
|
{isText && (
|
||||||
|
<div className="file-page__post-comments">
|
||||||
|
<CommentsList uri={uri} linkedComment={linkedComment} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</Page>
|
</Page>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
@import 'component/notification';
|
@import 'component/notification';
|
||||||
@import 'component/nudge';
|
@import 'component/nudge';
|
||||||
@import 'component/pagination';
|
@import 'component/pagination';
|
||||||
|
@import 'component/post';
|
||||||
@import 'component/purchase';
|
@import 'component/purchase';
|
||||||
@import 'component/placeholder';
|
@import 'component/placeholder';
|
||||||
@import 'component/progress';
|
@import 'component/progress';
|
||||||
|
|
|
@ -62,6 +62,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.claim-preview__wrapper {
|
.claim-preview__wrapper {
|
||||||
|
@include font-sans;
|
||||||
padding: var(--spacing-m);
|
padding: var(--spacing-m);
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.content__cover--text {
|
||||||
|
margin: 10rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
.content__cover--theater-mode {
|
.content__cover--theater-mode {
|
||||||
@extend .content__cover;
|
@extend .content__cover;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
|
@ -174,8 +178,8 @@
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
|
|
||||||
&.content__loading--document {
|
&.content__loading--document {
|
||||||
background-color: var(--color-card-background);
|
background-color: var(--color-background);
|
||||||
padding: calc(var(--spacing-xl) * 3) 0;
|
padding: calc(var(--spacing-xl) * 5) 0;
|
||||||
|
|
||||||
.content__loading-text {
|
.content__loading-text {
|
||||||
color: var(--color-text);
|
color: var(--color-text);
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
margin-top: var(--spacing-l);
|
margin-top: var(--spacing-l);
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-page__md {
|
.file-page__text {
|
||||||
.card {
|
.card {
|
||||||
border-bottom-left-radius: 0;
|
border-bottom-left-radius: 0;
|
||||||
border-bottom-right-radius: 0;
|
border-bottom-right-radius: 0;
|
||||||
|
@ -22,16 +22,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.card + .file-render {
|
.media__actions {
|
||||||
margin-top: 0;
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
.card {
|
.file-page__secondary-content {
|
||||||
border-top-left-radius: 0;
|
display: flex;
|
||||||
border-top-right-radius: 0;
|
flex-direction: column;
|
||||||
border-bottom-left-radius: var(--border-radius);
|
padding: 0 var(--spacing-m);
|
||||||
border-bottom-right-radius: var(--border-radius);
|
|
||||||
border-top: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,27 +83,6 @@
|
||||||
max-height: none;
|
max-height: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-render--document {
|
|
||||||
height: auto;
|
|
||||||
max-height: none;
|
|
||||||
overflow: auto;
|
|
||||||
margin-bottom: var(--spacing-l);
|
|
||||||
|
|
||||||
.markdown-preview {
|
|
||||||
height: 100%;
|
|
||||||
width: 40rem;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
max-width: unset;
|
|
||||||
min-width: unset;
|
|
||||||
|
|
||||||
@media (max-width: $breakpoint-small) {
|
|
||||||
width: 100%;
|
|
||||||
padding: var(--spacing-s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.file-render__header {
|
.file-render__header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
@ -155,6 +132,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.file-viewer--document {
|
||||||
|
margin-top: var(--spacing-l);
|
||||||
|
|
||||||
|
@media (min-width: $breakpoint-small) {
|
||||||
|
margin-top: var(--spacing-xl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.file-render__viewer--three {
|
.file-render__viewer--three {
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
|
@ -36,7 +36,6 @@
|
||||||
|
|
||||||
.main-wrapper__inner--filepage {
|
.main-wrapper__inner--filepage {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
padding-top: var(--spacing-s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-wrapper__inner--theater-mode {
|
.main-wrapper__inner--theater-mode {
|
||||||
|
@ -65,10 +64,11 @@
|
||||||
max-width: var(--page-max-width--filepage);
|
max-width: var(--page-max-width--filepage);
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
|
margin-top: var(--spacing-m);
|
||||||
|
padding: 0 var(--spacing-m);
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
padding-left: var(--spacing-m);
|
|
||||||
padding-right: var(--spacing-m);
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
> :first-child {
|
> :first-child {
|
||||||
|
@ -77,7 +77,7 @@
|
||||||
|
|
||||||
.file-page__secondary-content {
|
.file-page__secondary-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: row;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: var(--spacing-m);
|
margin-top: var(--spacing-m);
|
||||||
|
@ -94,6 +94,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.file-page__post-comments {
|
||||||
|
margin-top: var(--spacing-l);
|
||||||
|
|
||||||
|
@media (min-width: $breakpoint-small) {
|
||||||
|
padding: var(--spacing-m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.file-page__info {
|
.file-page__info {
|
||||||
margin-top: var(--spacing-m);
|
margin-top: var(--spacing-m);
|
||||||
}
|
}
|
||||||
|
@ -121,6 +129,7 @@
|
||||||
|
|
||||||
@media (max-width: $breakpoint-small) {
|
@media (max-width: $breakpoint-small) {
|
||||||
padding: var(--spacing-xs);
|
padding: var(--spacing-xs);
|
||||||
|
flex-direction: column;
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,6 +192,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.main--text {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
.main__auth-content {
|
.main__auth-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
|
|
||||||
.media__subtitle--centered {
|
.media__subtitle--centered {
|
||||||
@extend .media__subtitle;
|
@extend .media__subtitle;
|
||||||
|
align-self: auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
@ -110,6 +111,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.media__actions {
|
.media__actions {
|
||||||
|
@include font-sans;
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
84
ui/scss/component/_post.scss
Normal file
84
ui/scss/component/_post.scss
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
.post {
|
||||||
|
$card-bg: var(--color-card-background);
|
||||||
|
$bg: var(--color-background);
|
||||||
|
@include font-serif;
|
||||||
|
|
||||||
|
.card {
|
||||||
|
border: 0;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
height: 20rem;
|
||||||
|
background-image: linear-gradient(to top, $bg, $card-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post {
|
||||||
|
height: 100%;
|
||||||
|
width: 43rem;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
max-width: unset;
|
||||||
|
min-width: unset;
|
||||||
|
|
||||||
|
.channel-staked__wrapper {
|
||||||
|
background-color: var(--color-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.channel-thumbnail {
|
||||||
|
@include handleChannelGif(2.5rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: $breakpoint-small) {
|
||||||
|
width: 100%;
|
||||||
|
padding: var(--spacing-s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post__title {
|
||||||
|
font-size: 2rem;
|
||||||
|
line-height: 1.2;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: var(--spacing-m);
|
||||||
|
font-weight: var(--font-weight-bold);
|
||||||
|
|
||||||
|
:first-child {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: var(--spacing-s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: $breakpoint-small) {
|
||||||
|
margin-top: var(--spacing-xl);
|
||||||
|
font-size: 3rem;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post__info {
|
||||||
|
@include font-sans;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
line-height: 0;
|
||||||
|
margin-bottom: var(--spacing-l);
|
||||||
|
font-size: var(--font-small);
|
||||||
|
|
||||||
|
.credit-amount {
|
||||||
|
margin-right: var(--spacing-s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.post__date {
|
||||||
|
font-size: var(--font-small);
|
||||||
|
color: var(--color-help);
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-render--document {
|
||||||
|
font-size: var(--font-large);
|
||||||
|
height: auto;
|
||||||
|
max-height: none;
|
||||||
|
overflow: auto;
|
||||||
|
margin-bottom: var(--spacing-l);
|
||||||
|
}
|
|
@ -115,7 +115,6 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: var(--spacing-l);
|
margin-top: var(--spacing-l);
|
||||||
margin-right: var(--spacing-s);
|
|
||||||
|
|
||||||
~ .section {
|
~ .section {
|
||||||
margin-top: var(--spacing-l);
|
margin-top: var(--spacing-l);
|
||||||
|
|
Loading…
Add table
Reference in a new issue