Explain that "Block" leads to modal with more options. (#7039)
## Issue 7035 Make it clearer that delegated mods can block via Block menu
This commit is contained in:
parent
4ddf75f836
commit
23f273356a
6 changed files with 87 additions and 16 deletions
|
@ -1718,6 +1718,10 @@
|
||||||
"Level %current_level%": "Level %current_level%",
|
"Level %current_level%": "Level %current_level%",
|
||||||
"Creator tools": "Creator tools",
|
"Creator tools": "Creator tools",
|
||||||
"Prevent this channel from interacting with you.": "Prevent this channel from interacting with you.",
|
"Prevent this channel from interacting with you.": "Prevent this channel from interacting with you.",
|
||||||
|
"Choose a permanent or temporary ban.": "Choose a permanent or temporary ban.",
|
||||||
|
"Personal | Moderator | Admin": "Personal | Moderator | Admin",
|
||||||
|
"Personal | Moderator": "Personal | Moderator",
|
||||||
|
"Personal | Admin": "Personal | Admin",
|
||||||
"Hide this channel for you only.": "Hide this channel for you only.",
|
"Hide this channel for you only.": "Hide this channel for you only.",
|
||||||
"Interacting as %channelName%": "Interacting as %channelName%",
|
"Interacting as %channelName%": "Interacting as %channelName%",
|
||||||
"Page Not Found": "Page Not Found",
|
"Page Not Found": "Page Not Found",
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { doOpenModal } from 'redux/actions/app';
|
||||||
import { doSetPlayingUri } from 'redux/actions/content';
|
import { doSetPlayingUri } from 'redux/actions/content';
|
||||||
import { selectActiveChannelClaim } from 'redux/selectors/app';
|
import { selectActiveChannelClaim } from 'redux/selectors/app';
|
||||||
import { selectPlayingUri } from 'redux/selectors/content';
|
import { selectPlayingUri } from 'redux/selectors/content';
|
||||||
|
import { selectModerationDelegatorsById } from 'redux/selectors/comments';
|
||||||
import CommentMenuList from './view';
|
import CommentMenuList from './view';
|
||||||
|
|
||||||
const select = (state, props) => ({
|
const select = (state, props) => ({
|
||||||
|
@ -16,6 +16,7 @@ const select = (state, props) => ({
|
||||||
contentChannelPermanentUrl: makeSelectChannelPermUrlForClaimUri(props.uri)(state),
|
contentChannelPermanentUrl: makeSelectChannelPermUrlForClaimUri(props.uri)(state),
|
||||||
activeChannelClaim: selectActiveChannelClaim(state),
|
activeChannelClaim: selectActiveChannelClaim(state),
|
||||||
playingUri: selectPlayingUri(state),
|
playingUri: selectPlayingUri(state),
|
||||||
|
moderationDelegatorsById: selectModerationDelegatorsById(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = (dispatch) => ({
|
const perform = (dispatch) => ({
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { MenuList, MenuItem } from '@reach/menu-button';
|
||||||
import ChannelThumbnail from 'component/channelThumbnail';
|
import ChannelThumbnail from 'component/channelThumbnail';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
import { parseURI } from 'lbry-redux';
|
import { parseURI } from 'lbry-redux';
|
||||||
|
import { getChannelFromClaim } from 'util/claim';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
uri: ?string,
|
uri: ?string,
|
||||||
|
@ -24,6 +25,7 @@ type Props = {
|
||||||
contentChannelPermanentUrl: any,
|
contentChannelPermanentUrl: any,
|
||||||
activeChannelClaim: ?ChannelClaim,
|
activeChannelClaim: ?ChannelClaim,
|
||||||
playingUri: ?PlayingUri,
|
playingUri: ?PlayingUri,
|
||||||
|
moderationDelegatorsById: { [string]: { global: boolean, delegators: { name: string, claimId: string } } },
|
||||||
// --- perform ---
|
// --- perform ---
|
||||||
openModal: (id: string, {}) => void,
|
openModal: (id: string, {}) => void,
|
||||||
clearPlayingUri: () => void,
|
clearPlayingUri: () => void,
|
||||||
|
@ -50,6 +52,7 @@ function CommentMenuList(props: Props) {
|
||||||
handleEditComment,
|
handleEditComment,
|
||||||
commentModAddDelegate,
|
commentModAddDelegate,
|
||||||
playingUri,
|
playingUri,
|
||||||
|
moderationDelegatorsById,
|
||||||
disableEdit,
|
disableEdit,
|
||||||
disableRemove,
|
disableRemove,
|
||||||
openModal,
|
openModal,
|
||||||
|
@ -57,7 +60,15 @@ function CommentMenuList(props: Props) {
|
||||||
setQuickReply,
|
setQuickReply,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const contentChannelClaim = getChannelFromClaim(claim);
|
||||||
|
const activeModeratorInfo = activeChannelClaim && moderationDelegatorsById[activeChannelClaim.claim_id];
|
||||||
const activeChannelIsCreator = activeChannelClaim && activeChannelClaim.permanent_url === contentChannelPermanentUrl;
|
const activeChannelIsCreator = activeChannelClaim && activeChannelClaim.permanent_url === contentChannelPermanentUrl;
|
||||||
|
const activeChannelIsAdmin = activeChannelClaim && activeModeratorInfo && activeModeratorInfo.global;
|
||||||
|
const activeChannelIsModerator =
|
||||||
|
activeChannelClaim &&
|
||||||
|
contentChannelClaim &&
|
||||||
|
activeModeratorInfo &&
|
||||||
|
Object.values(activeModeratorInfo.delegators).includes(contentChannelClaim.claim_id);
|
||||||
|
|
||||||
function handlePinComment(commentId, claimId, remove) {
|
function handlePinComment(commentId, claimId, remove) {
|
||||||
pinComment(commentId, claimId, remove);
|
pinComment(commentId, claimId, remove);
|
||||||
|
@ -91,6 +102,59 @@ function CommentMenuList(props: Props) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getBlockOptionElem() {
|
||||||
|
const isPersonalBlockTheOnlyOption = !activeChannelIsModerator && !activeChannelIsAdmin;
|
||||||
|
const isTimeoutBlockAvailable = (claim && claim.is_my_output) || activeChannelIsModerator;
|
||||||
|
const personalPermanentBlockOnly = isPersonalBlockTheOnlyOption && !isTimeoutBlockAvailable;
|
||||||
|
|
||||||
|
function getSubtitle() {
|
||||||
|
if (personalPermanentBlockOnly) {
|
||||||
|
return {
|
||||||
|
line1: __('Prevent this channel from interacting with you.'),
|
||||||
|
line2: null,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
if (activeChannelIsModerator && activeChannelIsAdmin) {
|
||||||
|
return {
|
||||||
|
line1: __('Personal | Moderator | Admin'),
|
||||||
|
line2: __('Choose a permanent or temporary ban.'),
|
||||||
|
};
|
||||||
|
} else if (activeChannelIsModerator && !activeChannelIsAdmin) {
|
||||||
|
return {
|
||||||
|
line1: __('Personal | Moderator'),
|
||||||
|
line2: __('Choose a permanent or temporary ban.'),
|
||||||
|
};
|
||||||
|
} else if (!activeChannelIsModerator && activeChannelIsAdmin) {
|
||||||
|
return {
|
||||||
|
line1: __('Personal | Admin'),
|
||||||
|
line2: __('Choose a permanent or temporary ban.'),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
line1: null,
|
||||||
|
line2: __('Choose a permanent or temporary ban.'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const subtitle = getSubtitle();
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="menu__link">
|
||||||
|
<Icon aria-hidden icon={ICONS.BLOCK} />
|
||||||
|
{__('Block')}
|
||||||
|
</div>
|
||||||
|
{subtitle.line1 && <span className="comment__menu-help">{subtitle.line1}</span>}
|
||||||
|
{subtitle.line2 && (
|
||||||
|
<span className="comment__menu-help">
|
||||||
|
{subtitle.line2} {!personalPermanentBlockOnly && <Icon aria-hidden icon={ICONS.EXTERNAL} />}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MenuList className="menu__list">
|
<MenuList className="menu__list">
|
||||||
{activeChannelIsCreator && <div className="comment__menu-title">{__('Creator tools')}</div>}
|
{activeChannelIsCreator && <div className="comment__menu-title">{__('Creator tools')}</div>}
|
||||||
|
@ -142,13 +206,7 @@ function CommentMenuList(props: Props) {
|
||||||
|
|
||||||
{!commentIsMine && (
|
{!commentIsMine && (
|
||||||
<MenuItem className="comment__menu-option" onSelect={handleCommentBlock}>
|
<MenuItem className="comment__menu-option" onSelect={handleCommentBlock}>
|
||||||
<div className="menu__link">
|
{getBlockOptionElem()}
|
||||||
<Icon aria-hidden icon={ICONS.BLOCK} />
|
|
||||||
{__('Block')}
|
|
||||||
</div>
|
|
||||||
{activeChannelIsCreator && (
|
|
||||||
<span className="comment__menu-help">{__('Prevent this channel from interacting with you.')}</span>
|
|
||||||
)}
|
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import Icon from 'component/common/icon';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import usePersistedState from 'effects/use-persisted-state';
|
import usePersistedState from 'effects/use-persisted-state';
|
||||||
import { Modal } from 'modal/modal';
|
import { Modal } from 'modal/modal';
|
||||||
|
import { getChannelFromClaim } from 'util/claim';
|
||||||
|
|
||||||
const TAB = {
|
const TAB = {
|
||||||
PERSONAL: 'personal',
|
PERSONAL: 'personal',
|
||||||
|
@ -49,14 +50,7 @@ export default function ModalBlockChannel(props: Props) {
|
||||||
commentModBlockAsModerator,
|
commentModBlockAsModerator,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const contentChannelClaim = !contentClaim
|
const contentChannelClaim = getChannelFromClaim(contentClaim);
|
||||||
? null
|
|
||||||
: contentClaim.value_type === 'channel'
|
|
||||||
? contentClaim
|
|
||||||
: contentClaim.signing_channel && contentClaim.is_channel_signature_valid
|
|
||||||
? contentClaim.signing_channel
|
|
||||||
: null;
|
|
||||||
|
|
||||||
const activeModeratorInfo = activeChannelClaim && moderationDelegatorsById[activeChannelClaim.claim_id];
|
const activeModeratorInfo = activeChannelClaim && moderationDelegatorsById[activeChannelClaim.claim_id];
|
||||||
const activeChannelIsAdmin = activeChannelClaim && activeModeratorInfo && activeModeratorInfo.global;
|
const activeChannelIsAdmin = activeChannelClaim && activeModeratorInfo && activeModeratorInfo.global;
|
||||||
const activeChannelIsModerator =
|
const activeChannelIsModerator =
|
||||||
|
|
|
@ -353,6 +353,10 @@ $thumbnailWidthSmall: 1rem;
|
||||||
padding-left: calc(18px + var(--spacing-s));
|
padding-left: calc(18px + var(--spacing-s));
|
||||||
max-width: 15rem;
|
max-width: 15rem;
|
||||||
white-space: pre-line;
|
white-space: pre-line;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment__actions {
|
.comment__actions {
|
||||||
|
|
|
@ -9,3 +9,13 @@ export function getChannelIdFromClaim(claim: ?Claim) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getChannelFromClaim(claim: ?Claim) {
|
||||||
|
return !claim
|
||||||
|
? null
|
||||||
|
: claim.value_type === 'channel'
|
||||||
|
? claim
|
||||||
|
: claim.signing_channel && claim.is_channel_signature_valid
|
||||||
|
? claim.signing_channel
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue