Disable video previews in Comments and Post if author is below a certain level.
This commit is contained in:
parent
9192828505
commit
0d850742f5
9 changed files with 61 additions and 15 deletions
|
@ -30,6 +30,7 @@ YRBL_SAD_IMG_URL=https://cdn.lbryplayer.xyz/api/v3/streams/free/yrbl-sad/c2d9649
|
||||||
ENABLE_COMMENT_REACTIONS=true
|
ENABLE_COMMENT_REACTIONS=true
|
||||||
ENABLE_FILE_REACTIONS=false
|
ENABLE_FILE_REACTIONS=false
|
||||||
ENABLE_CREATOR_REACTIONS=false
|
ENABLE_CREATOR_REACTIONS=false
|
||||||
|
CHANNEL_STAKED_LEVEL_VIDEO_COMMENTS=4
|
||||||
|
|
||||||
# OG
|
# OG
|
||||||
OG_TITLE_SUFFIX=| lbry.tv
|
OG_TITLE_SUFFIX=| lbry.tv
|
||||||
|
|
|
@ -35,6 +35,7 @@ const config = {
|
||||||
ENABLE_COMMENT_REACTIONS: process.env.ENABLE_COMMENT_REACTIONS === 'true',
|
ENABLE_COMMENT_REACTIONS: process.env.ENABLE_COMMENT_REACTIONS === 'true',
|
||||||
ENABLE_FILE_REACTIONS: process.env.ENABLE_FILE_REACTIONS === 'true',
|
ENABLE_FILE_REACTIONS: process.env.ENABLE_FILE_REACTIONS === 'true',
|
||||||
ENABLE_CREATOR_REACTIONS: process.env.ENABLE_CREATOR_REACTIONS === 'true',
|
ENABLE_CREATOR_REACTIONS: process.env.ENABLE_CREATOR_REACTIONS === 'true',
|
||||||
|
CHANNEL_STAKED_LEVEL_VIDEO_COMMENTS: process.env.CHANNEL_STAKED_LEVEL_VIDEO_COMMENTS,
|
||||||
SIMPLE_SITE: process.env.SIMPLE_SITE === 'true',
|
SIMPLE_SITE: process.env.SIMPLE_SITE === 'true',
|
||||||
SHOW_ADS: process.env.SHOW_ADS === 'true',
|
SHOW_ADS: process.env.SHOW_ADS === 'true',
|
||||||
PINNED_URI_1: process.env.PINNED_URI_1,
|
PINNED_URI_1: process.env.PINNED_URI_1,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { makeSelectThumbnailForUri, selectMyChannelClaims } from 'lbry-redux';
|
import { makeSelectStakedLevelForChannelUri, makeSelectThumbnailForUri, selectMyChannelClaims } from 'lbry-redux';
|
||||||
import { doCommentUpdate } from 'redux/actions/comments';
|
import { doCommentUpdate } from 'redux/actions/comments';
|
||||||
import { makeSelectChannelIsMuted } from 'redux/selectors/blocked';
|
import { makeSelectChannelIsMuted } from 'redux/selectors/blocked';
|
||||||
import { doToast } from 'redux/actions/notifications';
|
import { doToast } from 'redux/actions/notifications';
|
||||||
|
@ -18,6 +18,7 @@ const select = (state, props) => ({
|
||||||
activeChannelClaim: selectActiveChannelClaim(state),
|
activeChannelClaim: selectActiveChannelClaim(state),
|
||||||
myChannels: selectMyChannelClaims(state),
|
myChannels: selectMyChannelClaims(state),
|
||||||
playingUri: selectPlayingUri(state),
|
playingUri: selectPlayingUri(state),
|
||||||
|
stakedLevel: makeSelectStakedLevelForChannelUri(props.authorUri)(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = (dispatch) => ({
|
const perform = (dispatch) => ({
|
||||||
|
|
|
@ -49,6 +49,7 @@ type Props = {
|
||||||
commentIdentityChannel: any,
|
commentIdentityChannel: any,
|
||||||
activeChannelClaim: ?ChannelClaim,
|
activeChannelClaim: ?ChannelClaim,
|
||||||
playingUri: ?PlayingUri,
|
playingUri: ?PlayingUri,
|
||||||
|
stakedLevel: number,
|
||||||
};
|
};
|
||||||
|
|
||||||
const LENGTH_TO_COLLAPSE = 300;
|
const LENGTH_TO_COLLAPSE = 300;
|
||||||
|
@ -75,6 +76,7 @@ function Comment(props: Props) {
|
||||||
isPinned,
|
isPinned,
|
||||||
othersReacts,
|
othersReacts,
|
||||||
playingUri,
|
playingUri,
|
||||||
|
stakedLevel,
|
||||||
} = props;
|
} = props;
|
||||||
const {
|
const {
|
||||||
push,
|
push,
|
||||||
|
@ -254,10 +256,20 @@ function Comment(props: Props) {
|
||||||
</div>
|
</div>
|
||||||
) : editedMessage.length >= LENGTH_TO_COLLAPSE ? (
|
) : editedMessage.length >= LENGTH_TO_COLLAPSE ? (
|
||||||
<Expandable>
|
<Expandable>
|
||||||
<MarkdownPreview content={message} promptLinks parentCommentId={commentId} />
|
<MarkdownPreview
|
||||||
|
content={message}
|
||||||
|
promptLinks
|
||||||
|
parentCommentId={commentId}
|
||||||
|
stakedLevel={stakedLevel}
|
||||||
|
/>
|
||||||
</Expandable>
|
</Expandable>
|
||||||
) : (
|
) : (
|
||||||
<MarkdownPreview content={message} promptLinks parentCommentId={commentId} />
|
<MarkdownPreview
|
||||||
|
content={message}
|
||||||
|
promptLinks
|
||||||
|
parentCommentId={commentId}
|
||||||
|
stakedLevel={stakedLevel}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ import defaultSchema from 'hast-util-sanitize/lib/github.json';
|
||||||
import { formatedLinks, inlineLinks } from 'util/remark-lbry';
|
import { formatedLinks, inlineLinks } from 'util/remark-lbry';
|
||||||
import { formattedTimestamp, inlineTimestamp } from 'util/remark-timestamp';
|
import { formattedTimestamp, inlineTimestamp } from 'util/remark-timestamp';
|
||||||
import ZoomableImage from 'component/zoomableImage';
|
import ZoomableImage from 'component/zoomableImage';
|
||||||
|
import { CHANNEL_STAKED_LEVEL_VIDEO_COMMENTS } from 'config';
|
||||||
|
|
||||||
type SimpleTextProps = {
|
type SimpleTextProps = {
|
||||||
children?: React.Node,
|
children?: React.Node,
|
||||||
|
@ -32,6 +33,7 @@ type MarkdownProps = {
|
||||||
className?: string,
|
className?: string,
|
||||||
parentCommentId?: string,
|
parentCommentId?: string,
|
||||||
isMarkdownPost?: boolean,
|
isMarkdownPost?: boolean,
|
||||||
|
stakedLevel?: number,
|
||||||
};
|
};
|
||||||
|
|
||||||
// ****************************************************************************
|
// ****************************************************************************
|
||||||
|
@ -93,7 +95,7 @@ const REPLACE_REGEX = /(<iframe\s+src=["'])(.*?(?=))(["']\s*><\/iframe>)/g;
|
||||||
// ****************************************************************************
|
// ****************************************************************************
|
||||||
|
|
||||||
const MarkdownPreview = (props: MarkdownProps) => {
|
const MarkdownPreview = (props: MarkdownProps) => {
|
||||||
const { content, strip, simpleLinks, noDataStore, className, parentCommentId, isMarkdownPost } = props;
|
const { content, strip, simpleLinks, noDataStore, className, parentCommentId, isMarkdownPost, stakedLevel } = props;
|
||||||
const strippedContent = content
|
const strippedContent = content
|
||||||
? content.replace(REPLACE_REGEX, (iframeHtml, y, iframeSrc) => {
|
? content.replace(REPLACE_REGEX, (iframeHtml, y, iframeSrc) => {
|
||||||
// Let the browser try to create an iframe to see if the markup is valid
|
// Let the browser try to create an iframe to see if the markup is valid
|
||||||
|
@ -119,12 +121,13 @@ const MarkdownPreview = (props: MarkdownProps) => {
|
||||||
remarkReactComponents: {
|
remarkReactComponents: {
|
||||||
a: noDataStore
|
a: noDataStore
|
||||||
? SimpleLink
|
? SimpleLink
|
||||||
: linkProps => (
|
: (linkProps) => (
|
||||||
<MarkdownLink
|
<MarkdownLink
|
||||||
{...linkProps}
|
{...linkProps}
|
||||||
parentCommentId={parentCommentId}
|
parentCommentId={parentCommentId}
|
||||||
isMarkdownPost={isMarkdownPost}
|
isMarkdownPost={isMarkdownPost}
|
||||||
simpleLinks={simpleLinks}
|
simpleLinks={simpleLinks}
|
||||||
|
allowPreview={stakedLevel && stakedLevel >= CHANNEL_STAKED_LEVEL_VIDEO_COMMENTS}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
// Workaraund of remarkOptions.Fragment
|
// Workaraund of remarkOptions.Fragment
|
||||||
|
|
|
@ -6,6 +6,8 @@ import {
|
||||||
makeSelectDownloadPathForUri,
|
makeSelectDownloadPathForUri,
|
||||||
makeSelectStreamingUrlForUri,
|
makeSelectStreamingUrlForUri,
|
||||||
SETTINGS,
|
SETTINGS,
|
||||||
|
makeSelectStakedLevelForChannelUri,
|
||||||
|
makeSelectChannelForClaimUri,
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||||
import { makeSelectFileRenderModeForUri, makeSelectFileExtensionForUri } from 'redux/selectors/content';
|
import { makeSelectFileRenderModeForUri, makeSelectFileExtensionForUri } from 'redux/selectors/content';
|
||||||
|
@ -13,9 +15,11 @@ import FileRender from './view';
|
||||||
|
|
||||||
const select = (state, props) => {
|
const select = (state, props) => {
|
||||||
const autoplay = props.embedded ? false : makeSelectClientSetting(SETTINGS.AUTOPLAY)(state);
|
const autoplay = props.embedded ? false : makeSelectClientSetting(SETTINGS.AUTOPLAY)(state);
|
||||||
|
const channelUri = makeSelectChannelForClaimUri(props.uri)(state);
|
||||||
return {
|
return {
|
||||||
currentTheme: makeSelectClientSetting(SETTINGS.THEME)(state),
|
currentTheme: makeSelectClientSetting(SETTINGS.THEME)(state),
|
||||||
claim: makeSelectClaimForUri(props.uri)(state),
|
claim: makeSelectClaimForUri(props.uri)(state),
|
||||||
|
stakedLevel: makeSelectStakedLevelForChannelUri(channelUri)(state),
|
||||||
thumbnail: makeSelectThumbnailForUri(props.uri)(state),
|
thumbnail: makeSelectThumbnailForUri(props.uri)(state),
|
||||||
contentType: makeSelectContentTypeForUri(props.uri)(state),
|
contentType: makeSelectContentTypeForUri(props.uri)(state),
|
||||||
downloadPath: makeSelectDownloadPathForUri(props.uri)(state),
|
downloadPath: makeSelectDownloadPathForUri(props.uri)(state),
|
||||||
|
|
|
@ -35,6 +35,7 @@ type Props = {
|
||||||
thumbnail: string,
|
thumbnail: string,
|
||||||
desktopPlayStartTime?: number,
|
desktopPlayStartTime?: number,
|
||||||
className?: string,
|
className?: string,
|
||||||
|
stakedLevel?: number,
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileRender extends React.PureComponent<Props> {
|
class FileRender extends React.PureComponent<Props> {
|
||||||
|
@ -78,6 +79,7 @@ class FileRender extends React.PureComponent<Props> {
|
||||||
uri,
|
uri,
|
||||||
renderMode,
|
renderMode,
|
||||||
desktopPlayStartTime,
|
desktopPlayStartTime,
|
||||||
|
stakedLevel,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const source = streamingUrl;
|
const source = streamingUrl;
|
||||||
|
|
||||||
|
@ -110,6 +112,7 @@ class FileRender extends React.PureComponent<Props> {
|
||||||
}}
|
}}
|
||||||
renderMode={renderMode}
|
renderMode={renderMode}
|
||||||
theme={currentTheme}
|
theme={currentTheme}
|
||||||
|
stakedLevel={stakedLevel}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case RENDER_MODES.DOCX:
|
case RENDER_MODES.DOCX:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// @flow
|
// @flow
|
||||||
import { KNOWN_APP_DOMAINS } from 'config';
|
import { KNOWN_APP_DOMAINS, SIMPLE_SITE } from 'config';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { isURIValid } from 'lbry-redux';
|
import { isURIValid } from 'lbry-redux';
|
||||||
|
@ -10,6 +10,7 @@ type Props = {
|
||||||
href: string,
|
href: string,
|
||||||
title?: string,
|
title?: string,
|
||||||
embed?: boolean,
|
embed?: boolean,
|
||||||
|
allowPreview?: boolean,
|
||||||
children: React.Node,
|
children: React.Node,
|
||||||
parentCommentId?: string,
|
parentCommentId?: string,
|
||||||
isMarkdownPost?: boolean,
|
isMarkdownPost?: boolean,
|
||||||
|
@ -17,7 +18,16 @@ type Props = {
|
||||||
};
|
};
|
||||||
|
|
||||||
function MarkdownLink(props: Props) {
|
function MarkdownLink(props: Props) {
|
||||||
const { children, href, title, embed = false, parentCommentId, isMarkdownPost, simpleLinks = false } = props;
|
const {
|
||||||
|
children,
|
||||||
|
href,
|
||||||
|
title,
|
||||||
|
embed = false,
|
||||||
|
allowPreview = false,
|
||||||
|
parentCommentId,
|
||||||
|
isMarkdownPost,
|
||||||
|
simpleLinks = false,
|
||||||
|
} = props;
|
||||||
|
|
||||||
let decodedUri;
|
let decodedUri;
|
||||||
try {
|
try {
|
||||||
|
@ -33,6 +43,7 @@ function MarkdownLink(props: Props) {
|
||||||
// Regex for url protocol
|
// Regex for url protocol
|
||||||
const protocolRegex = new RegExp('^(https?|lbry|mailto)+:', 'i');
|
const protocolRegex = new RegExp('^(https?|lbry|mailto)+:', 'i');
|
||||||
const protocol = href ? protocolRegex.exec(href) : null;
|
const protocol = href ? protocolRegex.exec(href) : null;
|
||||||
|
const isLbryLink = href.startsWith('lbry://');
|
||||||
|
|
||||||
let linkUrlObject;
|
let linkUrlObject;
|
||||||
try {
|
try {
|
||||||
|
@ -62,6 +73,10 @@ function MarkdownLink(props: Props) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return timestamp link if it starts with '?t=' (only possible from remark-timestamp).
|
||||||
|
// Return plain text if no valid url.
|
||||||
|
// Return external link if protocol is http or https.
|
||||||
|
// Return local link if protocol is lbry uri.
|
||||||
if (href.startsWith('?t=')) {
|
if (href.startsWith('?t=')) {
|
||||||
// Video timestamp markers
|
// Video timestamp markers
|
||||||
element = (
|
element = (
|
||||||
|
@ -80,10 +95,7 @@ function MarkdownLink(props: Props) {
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else if (!simpleLinks && ((protocol && protocol[0] === 'lbry:' && isURIValid(decodedUri)) || lbryUrlFromLink)) {
|
} else if (!simpleLinks && ((protocol && protocol[0] === 'lbry:' && isURIValid(decodedUri)) || lbryUrlFromLink)) {
|
||||||
// Return plain text if no valid url
|
element = allowPreview ? (
|
||||||
// Return external link if protocol is http or https
|
|
||||||
// Return local link if protocol is lbry uri
|
|
||||||
element = (
|
|
||||||
<ClaimLink
|
<ClaimLink
|
||||||
uri={lbryUrlFromLink || decodedUri}
|
uri={lbryUrlFromLink || decodedUri}
|
||||||
autoEmbed={embed}
|
autoEmbed={embed}
|
||||||
|
@ -92,13 +104,21 @@ function MarkdownLink(props: Props) {
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</ClaimLink>
|
</ClaimLink>
|
||||||
|
) : (
|
||||||
|
<Button
|
||||||
|
button="link"
|
||||||
|
iconRight={isLbryLink ? undefined : ICONS.EXTERNAL}
|
||||||
|
title={SIMPLE_SITE ? __("This channel isn't staking enough LBRY Credits for link previews.") : children}
|
||||||
|
label={children}
|
||||||
|
className="button--external-link"
|
||||||
|
navigate={isLbryLink ? href : undefined}
|
||||||
|
href={isLbryLink ? undefined : href}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
} else if (
|
} else if (
|
||||||
simpleLinks ||
|
simpleLinks ||
|
||||||
(protocol && (protocol[0] === 'http:' || protocol[0] === 'https:' || protocol[0] === 'mailto:'))
|
(protocol && (protocol[0] === 'http:' || protocol[0] === 'https:' || protocol[0] === 'mailto:'))
|
||||||
) {
|
) {
|
||||||
const isLbryLink = href.startsWith('lbry://');
|
|
||||||
|
|
||||||
element = (
|
element = (
|
||||||
<Button
|
<Button
|
||||||
button="link"
|
button="link"
|
||||||
|
|
|
@ -15,6 +15,7 @@ type Props = {
|
||||||
stream: string,
|
stream: string,
|
||||||
contentType: string,
|
contentType: string,
|
||||||
},
|
},
|
||||||
|
stakedLevel?: number,
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
|
@ -75,11 +76,11 @@ class DocumentViewer extends React.PureComponent<Props, State> {
|
||||||
|
|
||||||
renderDocument() {
|
renderDocument() {
|
||||||
const { content } = this.state;
|
const { content } = this.state;
|
||||||
const { source, theme, renderMode } = this.props;
|
const { source, theme, renderMode, stakedLevel } = this.props;
|
||||||
const { contentType } = source;
|
const { contentType } = source;
|
||||||
|
|
||||||
return renderMode === RENDER_MODES.MARKDOWN ? (
|
return renderMode === RENDER_MODES.MARKDOWN ? (
|
||||||
<MarkdownPreview content={content} isMarkdownPost promptLinks />
|
<MarkdownPreview content={content} isMarkdownPost promptLinks stakedLevel={stakedLevel} />
|
||||||
) : (
|
) : (
|
||||||
<CodeViewer value={content} contentType={contentType} theme={theme} />
|
<CodeViewer value={content} contentType={contentType} theme={theme} />
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue