Geoblock: show warning for own content
## Issue Contents aren't block if you own them, but need to tell creator that is it blocked for others. ## Change - Show a banner on Content and Channel Page for this scenario. - Hover tooltip is available for the full text. For mobile, tapping it reveals the message. Note that this only applies to the locale from where the creator is viewing it from. We can ignore locale, but would then need to display _all_ geo-restrictions related to the content in a list.
This commit is contained in:
parent
a4add6eab6
commit
58167210ea
6 changed files with 94 additions and 0 deletions
|
@ -3,6 +3,7 @@ import { SIMPLE_SITE } from 'config';
|
||||||
import * as CS from 'constants/claim_search';
|
import * as CS from 'constants/claim_search';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import React, { Fragment } from 'react';
|
import React, { Fragment } from 'react';
|
||||||
|
import GeoRestrictionInfo from 'component/geoRestictionInfo';
|
||||||
import HiddenNsfwClaims from 'component/hiddenNsfwClaims';
|
import HiddenNsfwClaims from 'component/hiddenNsfwClaims';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
|
@ -102,6 +103,8 @@ function ChannelContent(props: Props) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
|
<GeoRestrictionInfo uri={uri} />
|
||||||
|
|
||||||
{!fetching && Boolean(claimsInChannel) && !channelIsBlocked && !channelIsBlackListed && (
|
{!fetching && Boolean(claimsInChannel) && !channelIsBlocked && !channelIsBlackListed && (
|
||||||
<HiddenNsfwClaims uri={uri} />
|
<HiddenNsfwClaims uri={uri} />
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { normalizeURI } from 'util/lbryURI';
|
import { normalizeURI } from 'util/lbryURI';
|
||||||
import FilePrice from 'component/filePrice';
|
import FilePrice from 'component/filePrice';
|
||||||
|
import GeoRestrictionInfo from 'component/geoRestictionInfo';
|
||||||
import ClaimInsufficientCredits from 'component/claimInsufficientCredits';
|
import ClaimInsufficientCredits from 'component/claimInsufficientCredits';
|
||||||
import FileSubtitle from 'component/fileSubtitle';
|
import FileSubtitle from 'component/fileSubtitle';
|
||||||
import ClaimAuthor from 'component/claimAuthor';
|
import ClaimAuthor from 'component/claimAuthor';
|
||||||
|
@ -59,6 +60,7 @@ export default function FileTitleSection(props: Props) {
|
||||||
<span className="badge badge--tag-mature">{__('Mature')}</span>
|
<span className="badge badge--tag-mature">{__('Mature')}</span>
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
<GeoRestrictionInfo uri={uri} />
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
titleActions={<FilePrice uri={normalizeURI(uri)} type="filepage" />}
|
titleActions={<FilePrice uri={normalizeURI(uri)} type="filepage" />}
|
||||||
|
|
14
ui/component/geoRestictionInfo/index.js
Normal file
14
ui/component/geoRestictionInfo/index.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import GeoRestrictionInfo from './view';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { doOpenModal } from 'redux/actions/app';
|
||||||
|
import { selectGeoRestrictionForUri } from 'redux/selectors/claims';
|
||||||
|
|
||||||
|
const select = (state, props) => ({
|
||||||
|
geoRestriction: selectGeoRestrictionForUri(state, props.uri),
|
||||||
|
});
|
||||||
|
|
||||||
|
const perform = {
|
||||||
|
doOpenModal,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(select, perform)(GeoRestrictionInfo);
|
26
ui/component/geoRestictionInfo/style.scss
Normal file
26
ui/component/geoRestictionInfo/style.scss
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// "--color-text-error" is too bright, while "--color-error" isn't adjusted for
|
||||||
|
// light theme. Using the value of RED_COLOR from icon.jsx.
|
||||||
|
$text-color: #e2495e;
|
||||||
|
|
||||||
|
.geo-restriction-info {
|
||||||
|
display: flex;
|
||||||
|
margin: var(--spacing-m) 0;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
background: var(--color-card-background);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
color: $text-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.geo-restriction-info__container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: var(--spacing-l);
|
||||||
|
margin-bottom: var(--spacing-l);
|
||||||
|
}
|
||||||
|
|
||||||
|
.geo-restriction-info__title {
|
||||||
|
font-size: var(--font-large);
|
||||||
|
font-style: italic;
|
||||||
|
margin-left: var(--spacing-s);
|
||||||
|
}
|
47
ui/component/geoRestictionInfo/view.jsx
Normal file
47
ui/component/geoRestictionInfo/view.jsx
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
// @flow
|
||||||
|
import React from 'react';
|
||||||
|
import './style.scss';
|
||||||
|
import Card from 'component/common/card';
|
||||||
|
import Icon from 'component/common/icon';
|
||||||
|
import Tooltip from 'component/common/tooltip';
|
||||||
|
import * as ICONS from 'constants/icons';
|
||||||
|
import * as MODALS from 'constants/modal_types';
|
||||||
|
import { parseURI } from 'util/lbryURI';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
uri: string,
|
||||||
|
geoRestriction: ?GeoRestriction,
|
||||||
|
doOpenModal: (string, {}) => void,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function GeoRestrictionInfo(props: Props) {
|
||||||
|
const { uri, geoRestriction, doOpenModal } = props;
|
||||||
|
|
||||||
|
if (!geoRestriction) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { isChannel } = parseURI(uri);
|
||||||
|
const title = __(isChannel ? 'Channel unavailable' : 'Content unavailable');
|
||||||
|
const msg = <Card title={title} subtitle={__(geoRestriction.message || '')} />;
|
||||||
|
|
||||||
|
function showMsg() {
|
||||||
|
doOpenModal(MODALS.CONFIRM, {
|
||||||
|
title: title,
|
||||||
|
subtitle: __(geoRestriction.message || ''),
|
||||||
|
onConfirm: (closeModal) => closeModal(),
|
||||||
|
hideCancel: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Tooltip title={msg} followCursor>
|
||||||
|
<div className="geo-restriction-info" onClick={showMsg}>
|
||||||
|
<div className="geo-restriction-info__container">
|
||||||
|
<Icon icon={ICONS.EYE_OFF} size={24} />
|
||||||
|
<span className="geo-restriction-info__title">{title}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import * as ICONS from 'constants/icons';
|
||||||
import * as MODALS from 'constants/modal_types';
|
import * as MODALS from 'constants/modal_types';
|
||||||
import { formatCredits } from 'util/format-credits';
|
import { formatCredits } from 'util/format-credits';
|
||||||
import FileDetails from 'component/fileDetails';
|
import FileDetails from 'component/fileDetails';
|
||||||
|
import GeoRestictionInfo from 'component/geoRestictionInfo';
|
||||||
import ClaimAuthor from 'component/claimAuthor';
|
import ClaimAuthor from 'component/claimAuthor';
|
||||||
import FileTitle from 'component/fileTitle';
|
import FileTitle from 'component/fileTitle';
|
||||||
import FileActions from 'component/fileActions';
|
import FileActions from 'component/fileActions';
|
||||||
|
@ -53,6 +54,7 @@ function PostViewer(props: Props) {
|
||||||
return (
|
return (
|
||||||
<div className="post">
|
<div className="post">
|
||||||
<FileTitle uri={uri} className="post__title" />
|
<FileTitle uri={uri} className="post__title" />
|
||||||
|
<GeoRestictionInfo uri={uri} />
|
||||||
<div
|
<div
|
||||||
className={classnames('post__info', {
|
className={classnames('post__info', {
|
||||||
'post__info--expanded': expand !== EXPAND.NONE,
|
'post__info--expanded': expand !== EXPAND.NONE,
|
||||||
|
|
Loading…
Reference in a new issue