Add copy comment link menu option (#7224)

This commit is contained in:
saltrafael 2021-10-04 10:20:37 -03:00 committed by GitHub
parent 2ba6023926
commit d6e14b84db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 55 additions and 39 deletions

View file

@ -1,13 +1,13 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { makeSelectChannelPermUrlForClaimUri, makeSelectClaimIsMine, makeSelectClaimForUri } from 'lbry-redux';
import { doCommentPin, doCommentModAddDelegate } from 'redux/actions/comments';
import { doChannelMute } from 'redux/actions/blocked'; import { doChannelMute } from 'redux/actions/blocked';
// import { doSetActiveChannel } from 'redux/actions/app'; import { doCommentPin, doCommentModAddDelegate } from 'redux/actions/comments';
import { doOpenModal } from 'redux/actions/app'; import { doOpenModal } from 'redux/actions/app';
import { doSetPlayingUri } from 'redux/actions/content'; import { doSetPlayingUri } from 'redux/actions/content';
import { doToast } from 'redux/actions/notifications';
import { makeSelectChannelPermUrlForClaimUri, makeSelectClaimIsMine, makeSelectClaimForUri } from 'lbry-redux';
import { selectActiveChannelClaim } from 'redux/selectors/app'; import { selectActiveChannelClaim } from 'redux/selectors/app';
import { selectPlayingUri } from 'redux/selectors/content';
import { selectModerationDelegatorsById } from 'redux/selectors/comments'; import { selectModerationDelegatorsById } from 'redux/selectors/comments';
import { selectPlayingUri } from 'redux/selectors/content';
import CommentMenuList from './view'; import CommentMenuList from './view';
const select = (state, props) => ({ const select = (state, props) => ({
@ -24,9 +24,9 @@ const perform = (dispatch) => ({
clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })), clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })),
muteChannel: (channelUri) => dispatch(doChannelMute(channelUri)), muteChannel: (channelUri) => dispatch(doChannelMute(channelUri)),
pinComment: (commentId, claimId, remove) => dispatch(doCommentPin(commentId, claimId, remove)), pinComment: (commentId, claimId, remove) => dispatch(doCommentPin(commentId, claimId, remove)),
// setActiveChannel: channelId => dispatch(doSetActiveChannel(channelId)),
commentModAddDelegate: (modChanId, modChanName, creatorChannelClaim) => commentModAddDelegate: (modChanId, modChanName, creatorChannelClaim) =>
dispatch(doCommentModAddDelegate(modChanId, modChanName, creatorChannelClaim, true)), dispatch(doCommentModAddDelegate(modChanId, modChanName, creatorChannelClaim, true)),
doToast: (props) => dispatch(doToast(props)),
}); });
export default connect(select, perform)(CommentMenuList); export default connect(select, perform)(CommentMenuList);

View file

@ -1,12 +1,14 @@
// @flow // @flow
import { getChannelFromClaim } from 'util/claim';
import { MenuList, MenuItem } from '@reach/menu-button';
import { parseURI } from 'lbry-redux';
import { URL } from 'config';
import { useHistory } from 'react-router';
import * as ICONS from 'constants/icons'; import * as ICONS from 'constants/icons';
import * as MODALS from 'constants/modal_types'; import * as MODALS from 'constants/modal_types';
import React from 'react';
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 React from 'react';
import { getChannelFromClaim } from 'util/claim';
type Props = { type Props = {
uri: ?string, uri: ?string,
@ -18,7 +20,6 @@ type Props = {
disableEdit?: boolean, disableEdit?: boolean,
disableRemove?: boolean, disableRemove?: boolean,
supportAmount?: any, supportAmount?: any,
handleEditComment: () => void,
// --- select --- // --- select ---
claim: ?Claim, claim: ?Claim,
claimIsMine: boolean, claimIsMine: boolean,
@ -27,6 +28,8 @@ type Props = {
playingUri: ?PlayingUri, playingUri: ?PlayingUri,
moderationDelegatorsById: { [string]: { global: boolean, delegators: { name: string, claimId: string } } }, moderationDelegatorsById: { [string]: { global: boolean, delegators: { name: string, claimId: string } } },
// --- perform --- // --- perform ---
doToast: ({ message: string }) => void,
handleEditComment: () => void,
openModal: (id: string, {}) => void, openModal: (id: string, {}) => void,
clearPlayingUri: () => void, clearPlayingUri: () => void,
muteChannel: (string) => void, muteChannel: (string) => void,
@ -42,24 +45,29 @@ function CommentMenuList(props: Props) {
authorUri, authorUri,
commentIsMine, commentIsMine,
commentId, commentId,
muteChannel,
pinComment,
clearPlayingUri,
activeChannelClaim, activeChannelClaim,
contentChannelPermanentUrl, contentChannelPermanentUrl,
isTopLevel, isTopLevel,
isPinned, isPinned,
handleEditComment,
commentModAddDelegate,
playingUri, playingUri,
moderationDelegatorsById, moderationDelegatorsById,
disableEdit, disableEdit,
disableRemove, disableRemove,
openModal,
supportAmount, supportAmount,
doToast,
handleEditComment,
openModal,
clearPlayingUri,
muteChannel,
pinComment,
commentModAddDelegate,
setQuickReply, setQuickReply,
} = props; } = props;
const {
location: { pathname, search },
} = useHistory();
const contentChannelClaim = getChannelFromClaim(claim); const contentChannelClaim = getChannelFromClaim(claim);
const activeModeratorInfo = activeChannelClaim && moderationDelegatorsById[activeChannelClaim.claim_id]; const activeModeratorInfo = activeChannelClaim && moderationDelegatorsById[activeChannelClaim.claim_id];
const activeChannelIsCreator = activeChannelClaim && activeChannelClaim.permanent_url === contentChannelPermanentUrl; const activeChannelIsCreator = activeChannelClaim && activeChannelClaim.permanent_url === contentChannelPermanentUrl;
@ -70,10 +78,6 @@ function CommentMenuList(props: Props) {
activeModeratorInfo && activeModeratorInfo &&
Object.values(activeModeratorInfo.delegators).includes(contentChannelClaim.claim_id); Object.values(activeModeratorInfo.delegators).includes(contentChannelClaim.claim_id);
function handlePinComment(commentId, claimId, remove) {
pinComment(commentId, claimId, remove);
}
function handleDeleteComment() { function handleDeleteComment() {
if (playingUri && playingUri.source === 'comment') { if (playingUri && playingUri.source === 'comment') {
clearPlayingUri(); clearPlayingUri();
@ -87,14 +91,6 @@ function CommentMenuList(props: Props) {
}); });
} }
function handleCommentBlock() {
openModal(MODALS.BLOCK_CHANNEL, { contentUri: uri, commenterUri: authorUri });
}
function handleCommentMute() {
muteChannel(authorUri);
}
function assignAsModerator() { function assignAsModerator() {
if (activeChannelClaim && authorUri) { if (activeChannelClaim && authorUri) {
const { channelName, channelClaimId } = parseURI(authorUri); const { channelName, channelClaimId } = parseURI(authorUri);
@ -155,6 +151,15 @@ function CommentMenuList(props: Props) {
); );
} }
function handleCopyCommentLink() {
const urlParams = new URLSearchParams(search);
urlParams.delete('lc');
urlParams.append('lc', commentId);
navigator.clipboard
.writeText(`${URL}${pathname}?${urlParams.toString()}`)
.then(() => doToast({ message: __('Link copied.') }));
}
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>}
@ -162,7 +167,7 @@ function CommentMenuList(props: Props) {
{activeChannelIsCreator && isTopLevel && ( {activeChannelIsCreator && isTopLevel && (
<MenuItem <MenuItem
className="comment__menu-option menu__link" className="comment__menu-option menu__link"
onSelect={() => handlePinComment(commentId, claim ? claim.claim_id : '', isPinned)} onSelect={() => pinComment(commentId, claim ? claim.claim_id : '', isPinned)}
> >
<span className={'button__content'}> <span className={'button__content'}>
<Icon aria-hidden icon={ICONS.PIN} className={'icon'} /> <Icon aria-hidden icon={ICONS.PIN} className={'icon'} />
@ -205,20 +210,31 @@ function CommentMenuList(props: Props) {
)} )}
{!commentIsMine && ( {!commentIsMine && (
<MenuItem className="comment__menu-option" onSelect={handleCommentBlock}> <>
{getBlockOptionElem()} <MenuItem
</MenuItem> className="comment__menu-option"
onSelect={() => openModal(MODALS.BLOCK_CHANNEL, { contentUri: uri, commenterUri: authorUri })}
>
{getBlockOptionElem()}
</MenuItem>
<MenuItem className="comment__menu-option" onSelect={() => muteChannel(authorUri)}>
<div className="menu__link">
<Icon aria-hidden icon={ICONS.MUTE} />
{__('Mute')}
</div>
{activeChannelIsCreator && (
<span className="comment__menu-help">{__('Hide this channel for you only.')}</span>
)}
</MenuItem>
</>
)} )}
{!commentIsMine && ( {IS_WEB && (
<MenuItem className="comment__menu-option" onSelect={handleCommentMute}> <MenuItem className="comment__menu-option" onSelect={handleCopyCommentLink}>
<div className="menu__link"> <div className="menu__link">
<Icon aria-hidden icon={ICONS.MUTE} /> <Icon aria-hidden icon={ICONS.COPY_LINK} />
{__('Mute')} {__('Copy Link')}
</div> </div>
{activeChannelIsCreator && (
<span className="comment__menu-help">{__('Hide this channel for you only.')}</span>
)}
</MenuItem> </MenuItem>
)} )}