diff --git a/static/app-strings.json b/static/app-strings.json
index e5dcfad71..3b613400d 100644
--- a/static/app-strings.json
+++ b/static/app-strings.json
@@ -1302,7 +1302,7 @@
"Blocked": "Blocked",
"Unblock": "Unblock",
"Unblocking...": "Unblocking...",
- "Channel blocked. You will not see them again.": "Channel blocked. You will not see them again.",
+ "Channel \"%channel%\" blocked.": "Channel \"%channel%\" blocked.",
"Mute Channel": "Mute Channel",
"Unmute Channel": "Unmute Channel",
"Muted": "Muted",
@@ -1690,13 +1690,32 @@
"Transaction limit reached. Try reducing the Description length.": "Transaction limit reached. Try reducing the Description length.",
"You do not have any muted channels": "You do not have any muted channels",
"You do not have any blocked channels": "You do not have any blocked channels",
- "Blocked channels will be invisible to you in the app. They will not be able to comment on your content, or reply to you comments left on other channels' content.": "Blocked channels will be invisible to you in the app. They will not be able to comment on your content, or reply to you comments left on other channels' content.",
+ "You do not have any globally-blocked channels": "You do not have any globally-blocked channels",
+ "You do not have any blocked channels as a moderator": "You do not have any blocked channels as a moderator",
+ "Blocked channels will be invisible to you in the app. They will not be able to comment on your content, nor reply to your comments left on other channels' content.": "Blocked channels will be invisible to you in the app. They will not be able to comment on your content, nor reply to your comments left on other channels' content.",
"Muted channels will be invisible to you in the app. They will not know they are muted and can still interact with you and your content.": "Muted channels will be invisible to you in the app. They will not know they are muted and can still interact with you and your content.",
+ "List of channels that you have blocked as a moderator. To unblock a channel, notify the content creator.": "List of channels that you have blocked as a moderator. To unblock a channel, notify the content creator.",
+ "This is the global block list.": "This is the global block list.",
"This channel is blocked": "This channel is blocked",
"This channel is muted": "This channel is muted",
"Are you sure you want to view this content? Viewing will not unblock @%channel%": "Are you sure you want to view this content? Viewing will not unblock @%channel%",
"Are you sure you want to view this content? Viewing will not unmute @%channel%": "Are you sure you want to view this content? Viewing will not unmute @%channel%",
"View Content": "View Content",
+ "Global": "Global",
+ "Moderator": "Moderator",
+ "Global Unblock Channel": "Global Unblock Channel",
+ "Global Block Channel": "Global Block Channel",
+ "Moderator tools": "Moderator tools",
+ "Global Block": "Global Block",
+ "Block this channel as global admin": "Block this channel as global admin",
+ "Moderator Block": "Moderator Block",
+ "Block this channel on behalf of %creator%": "Block this channel on behalf of %creator%",
+ "creator": "creator",
+ "Invalid channel URL \"%url%\"": "Invalid channel URL \"%url%\"",
+ "Delegation": "Delegation",
+ "Add moderator": "Add moderator",
+ "Add moderators": "Add moderators",
+ "Add moderator channel URL (e.g. \"@lbry#3f\")": "Add moderator channel URL (e.g. \"@lbry#3f\")",
"Mute (m)": "Mute (m)",
"Playback Rate (<, >)": "Playback Rate (<, >)",
"Fullscreen (f)": "Fullscreen (f)",
diff --git a/ui/component/channelBlockButton/index.js b/ui/component/channelBlockButton/index.js
index 73398c5e0..50ca09e1e 100644
--- a/ui/component/channelBlockButton/index.js
+++ b/ui/component/channelBlockButton/index.js
@@ -1,14 +1,57 @@
import { connect } from 'react-redux';
-import { doCommentModUnBlock, doCommentModBlock } from 'redux/actions/comments';
-import { makeSelectChannelIsBlocked, makeSelectUriIsBlockingOrUnBlocking } from 'redux/selectors/comments';
+import { makeSelectClaimIdForUri } from 'lbry-redux';
+import {
+ doCommentModUnBlock,
+ doCommentModBlock,
+ doCommentModBlockAsAdmin,
+ doCommentModUnBlockAsAdmin,
+ doCommentModUnBlockAsModerator,
+ doCommentModBlockAsModerator,
+} from 'redux/actions/comments';
+import {
+ makeSelectChannelIsBlocked,
+ makeSelectChannelIsAdminBlocked,
+ makeSelectChannelIsModeratorBlockedForCreator,
+ makeSelectUriIsBlockingOrUnBlocking,
+ makeSelectIsTogglingForDelegator,
+} from 'redux/selectors/comments';
+
+import { BLOCK_LEVEL } from 'constants/comment';
import ChannelBlockButton from './view';
-const select = (state, props) => ({
- isBlocked: makeSelectChannelIsBlocked(props.uri)(state),
- isBlockingOrUnBlocking: makeSelectUriIsBlockingOrUnBlocking(props.uri)(state),
-});
+const select = (state, props) => {
+ let isBlocked;
+ let isToggling;
+
+ switch (props.blockLevel) {
+ default:
+ case BLOCK_LEVEL.SELF:
+ isBlocked = makeSelectChannelIsBlocked(props.uri)(state);
+ break;
+
+ case BLOCK_LEVEL.MODERATOR:
+ isBlocked = makeSelectChannelIsModeratorBlockedForCreator(props.uri, props.creatorUri)(state);
+ isToggling = makeSelectIsTogglingForDelegator(props.uri, props.creatorUri)(state);
+ break;
+
+ case BLOCK_LEVEL.ADMIN:
+ isBlocked = makeSelectChannelIsAdminBlocked(props.uri)(state);
+ break;
+ }
+
+ return {
+ isBlocked,
+ isToggling,
+ isBlockingOrUnBlocking: makeSelectUriIsBlockingOrUnBlocking(props.uri)(state),
+ creatorId: makeSelectClaimIdForUri(props.creatorUri)(state),
+ };
+};
export default connect(select, {
doCommentModUnBlock,
doCommentModBlock,
+ doCommentModUnBlockAsAdmin,
+ doCommentModBlockAsAdmin,
+ doCommentModUnBlockAsModerator,
+ doCommentModBlockAsModerator,
})(ChannelBlockButton);
diff --git a/ui/component/channelBlockButton/view.jsx b/ui/component/channelBlockButton/view.jsx
index 742205258..dce36b899 100644
--- a/ui/component/channelBlockButton/view.jsx
+++ b/ui/component/channelBlockButton/view.jsx
@@ -1,41 +1,95 @@
// @flow
import React from 'react';
import Button from 'component/button';
+import { BLOCK_LEVEL } from 'constants/comment';
+import { parseURI } from 'lbry-redux';
type Props = {
uri: string,
+ blockLevel?: string,
+ creatorUri?: string,
isBlocked: boolean,
isBlockingOrUnBlocking: boolean,
+ isToggling: boolean,
doCommentModUnBlock: (string, boolean) => void,
doCommentModBlock: (string, boolean) => void,
+ doCommentModUnBlockAsAdmin: (string, string) => void,
+ doCommentModBlockAsAdmin: (string, string) => void,
+ doCommentModUnBlockAsModerator: (string, string, string) => void,
+ doCommentModBlockAsModerator: (string, string, string) => void,
};
function ChannelBlockButton(props: Props) {
- const { uri, doCommentModUnBlock, doCommentModBlock, isBlocked, isBlockingOrUnBlocking } = props;
+ const {
+ uri,
+ blockLevel,
+ creatorUri,
+ doCommentModUnBlock,
+ doCommentModBlock,
+ doCommentModUnBlockAsAdmin,
+ doCommentModBlockAsAdmin,
+ doCommentModUnBlockAsModerator,
+ doCommentModBlockAsModerator,
+ isBlocked,
+ isBlockingOrUnBlocking,
+ isToggling,
+ } = props;
function handleClick() {
- if (isBlocked) {
- doCommentModUnBlock(uri, false);
- } else {
- doCommentModBlock(uri, false);
+ switch (blockLevel) {
+ default:
+ case BLOCK_LEVEL.SELF:
+ if (isBlocked) {
+ doCommentModUnBlock(uri, false);
+ } else {
+ doCommentModBlock(uri, false);
+ }
+ break;
+
+ case BLOCK_LEVEL.MODERATOR:
+ if (creatorUri) {
+ const { channelClaimId } = parseURI(creatorUri);
+ if (isBlocked) {
+ doCommentModUnBlockAsModerator(uri, channelClaimId, '');
+ } else {
+ doCommentModBlockAsModerator(uri, channelClaimId, '');
+ }
+ }
+ break;
+
+ case BLOCK_LEVEL.ADMIN:
+ if (isBlocked) {
+ doCommentModUnBlockAsAdmin(uri, '');
+ } else {
+ doCommentModBlockAsAdmin(uri, '');
+ }
+ break;
}
}
- return (
-
- );
+ ? __('Blocking...')
+ : __('Block');
+
+ case BLOCK_LEVEL.MODERATOR:
+ if (isToggling) {
+ return isBlocked ? __('Unblocking...') : __('Blocking...');
+ } else {
+ return isBlocked ? __('Unblock') : __('Block');
+ }
+ }
+ }
+
+ return ;
}
export default ChannelBlockButton;
diff --git a/ui/component/claimMenuList/index.js b/ui/component/claimMenuList/index.js
index 5b7ff2407..ee8a70625 100644
--- a/ui/component/claimMenuList/index.js
+++ b/ui/component/claimMenuList/index.js
@@ -13,8 +13,17 @@ import {
import { makeSelectChannelIsMuted } from 'redux/selectors/blocked';
import { doChannelMute, doChannelUnmute } from 'redux/actions/blocked';
import { doSetActiveChannel, doSetIncognito, doOpenModal } from 'redux/actions/app';
-import { doCommentModBlock, doCommentModUnBlock } from 'redux/actions/comments';
-import { makeSelectChannelIsBlocked } from 'redux/selectors/comments';
+import {
+ doCommentModBlock,
+ doCommentModUnBlock,
+ doCommentModBlockAsAdmin,
+ doCommentModUnBlockAsAdmin,
+} from 'redux/actions/comments';
+import {
+ selectHasAdminChannel,
+ makeSelectChannelIsBlocked,
+ makeSelectChannelIsAdminBlocked,
+} from 'redux/selectors/comments';
import { doToast } from 'redux/actions/notifications';
import { makeSelectSigningIsMine } from 'redux/selectors/content';
import { doChannelSubscribe, doChannelUnsubscribe } from 'redux/actions/subscriptions';
@@ -33,6 +42,8 @@ const select = (state, props) => {
channelIsBlocked: makeSelectChannelIsBlocked(props.uri)(state),
fileInfo: makeSelectFileInfoForUri(props.uri)(state),
isSubscribed: makeSelectIsSubscribed(props.channelUri, true)(state),
+ channelIsAdminBlocked: makeSelectChannelIsAdminBlocked(props.uri)(state),
+ isAdmin: selectHasAdminChannel(state),
claimInCollection: makeSelectCollectionForIdHasClaimUrl(props.collectionId, permanentUri)(state),
collectionName: makeSelectNameForCollectionId(props.collectionId)(state),
isMyCollection: makeSelectCollectionIsMine(props.collectionId)(state),
@@ -57,6 +68,9 @@ const perform = (dispatch) => ({
doChannelUnmute: (channelUri) => dispatch(doChannelUnmute(channelUri)),
doCommentModBlock: (channelUri) => dispatch(doCommentModBlock(channelUri)),
doCommentModUnBlock: (channelUri) => dispatch(doCommentModUnBlock(channelUri)),
+ doCommentModBlockAsAdmin: (commenterUri, blockerId) => dispatch(doCommentModBlockAsAdmin(commenterUri, blockerId)),
+ doCommentModUnBlockAsAdmin: (commenterUri, blockerId) =>
+ dispatch(doCommentModUnBlockAsAdmin(commenterUri, blockerId)),
doChannelSubscribe: (subscription) => dispatch(doChannelSubscribe(subscription)),
doChannelUnsubscribe: (subscription) => dispatch(doChannelUnsubscribe(subscription)),
doCollectionEdit: (collection, props) => dispatch(doCollectionEdit(collection, props)),
diff --git a/ui/component/claimMenuList/view.jsx b/ui/component/claimMenuList/view.jsx
index 9ba301a00..f770b0ec2 100644
--- a/ui/component/claimMenuList/view.jsx
+++ b/ui/component/claimMenuList/view.jsx
@@ -29,10 +29,14 @@ type Props = {
inline?: boolean,
channelIsMuted: boolean,
channelIsBlocked: boolean,
+ channelIsAdminBlocked: boolean,
+ isAdmin: boolean,
doChannelMute: (string) => void,
doChannelUnmute: (string) => void,
doCommentModBlock: (string) => void,
doCommentModUnBlock: (string) => void,
+ doCommentModBlockAsAdmin: (string, string) => void,
+ doCommentModUnBlockAsAdmin: (string, string) => void,
isRepost: boolean,
doCollectionEdit: (string, any) => void,
hasClaimInWatchLater: boolean,
@@ -62,9 +66,13 @@ function ClaimMenuList(props: Props) {
doChannelUnmute,
channelIsMuted,
channelIsBlocked,
+ channelIsAdminBlocked,
+ isAdmin,
doCommentModBlock,
doCommentModUnBlock,
isRepost,
+ doCommentModBlockAsAdmin,
+ doCommentModUnBlockAsAdmin,
doCollectionEdit,
hasClaimInWatchLater,
collectionId,
@@ -166,6 +174,14 @@ function ClaimMenuList(props: Props) {
openModal(MODALS.SEND_TIP, { uri, isSupport: true });
}
+ function handleToggleAdminBlock() {
+ if (channelIsAdminBlocked) {
+ doCommentModUnBlockAsAdmin(channelUri, '');
+ } else {
+ doCommentModBlockAsAdmin(channelUri, '');
+ }
+ }
+
function handleCopyLink() {
navigator.clipboard.writeText(shareUrl);
}
@@ -292,6 +308,15 @@ function ClaimMenuList(props: Props) {
+ {isAdmin && (
+
+ )}
+