Pop up Menu Fixes and Improvements

Pop up Menu Fixes and Improvements

Improve re-directs

Fix file deletion

Improve code, and more

Fix List Layout collection popup

Allow to edit list

Fix blocking when not logged or no channel

Fix Edit and Delete showing for not owned Lists

Fix actions breaking when not logged in

Fix List options not showing

Lint

Shorten logic

Lint
This commit is contained in:
saltrafael 2021-06-24 11:33:11 -03:00 committed by jessopb
parent fdca58727c
commit b164a5d1f4
9 changed files with 175 additions and 149 deletions

View file

@ -5,7 +5,6 @@ import {
makeSelectFileInfoForUri, makeSelectFileInfoForUri,
doPrepareEdit, doPrepareEdit,
makeSelectCollectionForIdHasClaimUrl, makeSelectCollectionForIdHasClaimUrl,
makeSelectNameForCollectionId,
makeSelectCollectionIsMine, makeSelectCollectionIsMine,
COLLECTIONS_CONSTS, COLLECTIONS_CONSTS,
makeSelectEditedCollectionForId, makeSelectEditedCollectionForId,
@ -34,20 +33,28 @@ import fs from 'fs';
const select = (state, props) => { const select = (state, props) => {
const claim = makeSelectClaimForUri(props.uri, false)(state); const claim = makeSelectClaimForUri(props.uri, false)(state);
const permanentUri = claim && claim.permanent_url; const repostedClaim = claim && claim.reposted_claim;
const contentClaim = repostedClaim || claim;
const contentSigningChannel = contentClaim && contentClaim.signing_channel;
const contentPermanentUri = contentClaim && contentClaim.permanent_url;
const contentChannelUri = (contentSigningChannel && contentSigningChannel.permanent_url) || contentPermanentUri;
return { return {
claim, claim,
repostedClaim,
contentClaim,
contentSigningChannel,
contentChannelUri,
claimIsMine: makeSelectSigningIsMine(props.uri)(state), claimIsMine: makeSelectSigningIsMine(props.uri)(state),
hasClaimInWatchLater: makeSelectCollectionForIdHasClaimUrl(COLLECTIONS_CONSTS.WATCH_LATER_ID, permanentUri)(state), hasClaimInWatchLater: makeSelectCollectionForIdHasClaimUrl(COLLECTIONS_CONSTS.WATCH_LATER_ID, contentPermanentUri)(state),
hasClaimInCustom: makeSelectCollectionForIdHasClaimUrl(COLLECTIONS_CONSTS.FAVORITES_ID, permanentUri)(state), hasClaimInCustom: makeSelectCollectionForIdHasClaimUrl(COLLECTIONS_CONSTS.FAVORITES_ID, contentPermanentUri)(state),
channelIsMuted: makeSelectChannelIsMuted(props.uri)(state), channelIsMuted: makeSelectChannelIsMuted(contentChannelUri)(state),
channelIsBlocked: makeSelectChannelIsBlocked(props.uri)(state), channelIsBlocked: makeSelectChannelIsBlocked(contentChannelUri)(state),
fileInfo: makeSelectFileInfoForUri(props.uri)(state), fileInfo: makeSelectFileInfoForUri(props.uri)(state),
isSubscribed: makeSelectIsSubscribed(props.channelUri, true)(state), isSubscribed: makeSelectIsSubscribed(contentChannelUri, true)(state),
channelIsAdminBlocked: makeSelectChannelIsAdminBlocked(props.uri)(state), channelIsAdminBlocked: makeSelectChannelIsAdminBlocked(props.uri)(state),
isAdmin: selectHasAdminChannel(state), isAdmin: selectHasAdminChannel(state),
claimInCollection: makeSelectCollectionForIdHasClaimUrl(props.collectionId, permanentUri)(state), claimInCollection: makeSelectCollectionForIdHasClaimUrl(props.collectionId, contentPermanentUri)(state),
collectionName: makeSelectNameForCollectionId(props.collectionId)(state),
isMyCollection: makeSelectCollectionIsMine(props.collectionId)(state), isMyCollection: makeSelectCollectionIsMine(props.collectionId)(state),
editedCollection: makeSelectEditedCollectionForId(props.collectionId)(state), editedCollection: makeSelectEditedCollectionForId(props.collectionId)(state),
isAuthenticated: Boolean(selectUserVerifiedEmail(state)), isAuthenticated: Boolean(selectUserVerifiedEmail(state)),
@ -71,7 +78,8 @@ const perform = (dispatch) => ({
doChannelUnmute: (channelUri) => dispatch(doChannelUnmute(channelUri)), doChannelUnmute: (channelUri) => dispatch(doChannelUnmute(channelUri)),
doCommentModBlock: (channelUri) => dispatch(doCommentModBlock(channelUri)), doCommentModBlock: (channelUri) => dispatch(doCommentModBlock(channelUri)),
doCommentModUnBlock: (channelUri) => dispatch(doCommentModUnBlock(channelUri)), doCommentModUnBlock: (channelUri) => dispatch(doCommentModUnBlock(channelUri)),
doCommentModBlockAsAdmin: (commenterUri, blockerId) => dispatch(doCommentModBlockAsAdmin(commenterUri, blockerId)), doCommentModBlockAsAdmin: (commenterUri, blockerId) =>
dispatch(doCommentModBlockAsAdmin(commenterUri, blockerId)),
doCommentModUnBlockAsAdmin: (commenterUri, blockerId) => doCommentModUnBlockAsAdmin: (commenterUri, blockerId) =>
dispatch(doCommentModUnBlockAsAdmin(commenterUri, blockerId)), dispatch(doCommentModUnBlockAsAdmin(commenterUri, blockerId)),
doChannelSubscribe: (subscription) => dispatch(doChannelSubscribe(subscription)), doChannelSubscribe: (subscription) => dispatch(doChannelSubscribe(subscription)),

View file

@ -23,8 +23,11 @@ type SubscriptionArgs = {
type Props = { type Props = {
uri: string, uri: string,
channelUri: string,
claim: ?Claim, claim: ?Claim,
repostedClaim: ?Claim,
contentClaim: ?Claim,
contentSigningChannel: ?Claim,
contentChannelUri: string,
openModal: (id: string, {}) => void, openModal: (id: string, {}) => void,
inline?: boolean, inline?: boolean,
channelIsMuted: boolean, channelIsMuted: boolean,
@ -37,12 +40,10 @@ type Props = {
doCommentModUnBlock: (string) => void, doCommentModUnBlock: (string) => void,
doCommentModBlockAsAdmin: (string, string) => void, doCommentModBlockAsAdmin: (string, string) => void,
doCommentModUnBlockAsAdmin: (string, string) => void, doCommentModUnBlockAsAdmin: (string, string) => void,
isRepost: boolean,
doCollectionEdit: (string, any) => void, doCollectionEdit: (string, any) => void,
hasClaimInWatchLater: boolean, hasClaimInWatchLater: boolean,
hasClaimInCustom: boolean, hasClaimInCustom: boolean,
claimInCollection: boolean, claimInCollection: boolean,
collectionName?: string,
collectionId: string, collectionId: string,
isMyCollection: boolean, isMyCollection: boolean,
doToast: ({ message: string, isError?: boolean }) => void, doToast: ({ message: string, isError?: boolean }) => void,
@ -60,8 +61,11 @@ type Props = {
function ClaimMenuList(props: Props) { function ClaimMenuList(props: Props) {
const { const {
uri, uri,
channelUri,
claim, claim,
repostedClaim,
contentClaim,
contentSigningChannel,
contentChannelUri,
openModal, openModal,
inline = false, inline = false,
doChannelMute, doChannelMute,
@ -72,14 +76,12 @@ function ClaimMenuList(props: Props) {
isAdmin, isAdmin,
doCommentModBlock, doCommentModBlock,
doCommentModUnBlock, doCommentModUnBlock,
isRepost,
doCommentModBlockAsAdmin, doCommentModBlockAsAdmin,
doCommentModUnBlockAsAdmin, doCommentModUnBlockAsAdmin,
doCollectionEdit, doCollectionEdit,
hasClaimInWatchLater, hasClaimInWatchLater,
hasClaimInCustom, hasClaimInCustom,
collectionId, collectionId,
collectionName,
isMyCollection, isMyCollection,
doToast, doToast,
claimIsMine, claimIsMine,
@ -92,15 +94,16 @@ function ClaimMenuList(props: Props) {
editedCollection, editedCollection,
isAuthenticated, isAuthenticated,
} = props; } = props;
const repostedContent = claim && claim.reposted_claim; const incognitoClaim = contentChannelUri && !contentChannelUri.includes('@');
const contentClaim = repostedContent || claim; const isChannel = !incognitoClaim && !contentSigningChannel;
const incognitoClaim = channelUri && !channelUri.includes('@'); const { channelName } = parseURI(contentChannelUri);
const signingChannel = claim && (claim.signing_channel || claim);
const permanentUrl = String(channelUri);
const isChannel = !incognitoClaim && signingChannel === claim;
const showDelete = claimIsMine || (fileInfo && (fileInfo.written_bytes > 0 || fileInfo.blobs_completed > 0)); const showDelete = claimIsMine || (fileInfo && (fileInfo.written_bytes > 0 || fileInfo.blobs_completed > 0));
const subscriptionLabel = isSubscribed ? __('Unfollow') : __('Follow'); const subscriptionLabel = __('%action%' + '%user%', {
action: isSubscribed ? __('Unfollow') : __('Follow'),
user: repostedClaim ? __(' @' + channelName) : '',
});
const lastCollectionName = 'Favorites'; const lastCollectionName = 'Favorites';
const lastCollectionId = COLLECTIONS_CONSTS.FAVORITES_ID;
const { push, replace } = useHistory(); const { push, replace } = useHistory();
if (!claim) { if (!claim) {
@ -121,36 +124,46 @@ function ClaimMenuList(props: Props) {
// $FlowFixMe // $FlowFixMe
(contentClaim.value.stream_type === 'audio' || contentClaim.value.stream_type === 'video'); (contentClaim.value.stream_type === 'audio' || contentClaim.value.stream_type === 'video');
function handleAdd(source, name, collectionId) {
doToast({
message: source ? __('Item removed from %name%', { name }) : __('Item added to %name%', { name }),
});
doCollectionEdit(collectionId, {
claims: [contentClaim],
remove: source,
type: 'playlist',
});
}
function handleFollow() { function handleFollow() {
const { channelName } = parseURI(permanentUrl);
const subscriptionHandler = isSubscribed ? doChannelUnsubscribe : doChannelSubscribe; const subscriptionHandler = isSubscribed ? doChannelUnsubscribe : doChannelSubscribe;
subscriptionHandler({ subscriptionHandler({
channelName: '@' + channelName, channelName: '@' + channelName,
uri: permanentUrl, uri: contentChannelUri,
notificationsDisabled: true, notificationsDisabled: true,
}); });
} }
function handleToggleMute() { function handleToggleMute() {
if (channelIsMuted) { if (channelIsMuted) {
doChannelUnmute(channelUri); doChannelUnmute(contentChannelUri);
} else { } else {
doChannelMute(channelUri); doChannelMute(contentChannelUri);
} }
} }
function handleToggleBlock() { function handleToggleBlock() {
if (channelIsBlocked) { if (channelIsBlocked) {
doCommentModUnBlock(channelUri); doCommentModUnBlock(contentChannelUri);
} else { } else {
doCommentModBlock(channelUri); doCommentModBlock(contentChannelUri);
} }
} }
function handleEdit() { function handleEdit() {
if (!isChannel) { if (!isChannel) {
const signingChannelName = signingChannel && signingChannel.name; const signingChannelName = contentSigningChannel && contentSigningChannel.name;
const uriObject: { streamName: string, streamClaimId: string, channelName?: string } = { const uriObject: { streamName: string, streamClaimId: string, channelName?: string } = {
streamName: claim.name, streamName: claim.name,
@ -170,10 +183,10 @@ function ClaimMenuList(props: Props) {
} }
function handleDelete() { function handleDelete() {
if (!isRepost && !isChannel) { if (!repostedClaim && !isChannel) {
openModal(MODALS.CONFIRM_FILE_REMOVE, { uri }); openModal(MODALS.CONFIRM_FILE_REMOVE, { uri, doGoBack: false });
} else { } else {
openModal(MODALS.CONFIRM_CLAIM_REVOKE, { claim, cb: !isRepost && (() => replace(`/$/${PAGES.CHANNELS}`)) }); openModal(MODALS.CONFIRM_CLAIM_REVOKE, { claim, cb: isChannel && (() => replace(`/$/${PAGES.CHANNELS}`)) });
} }
} }
@ -183,9 +196,9 @@ function ClaimMenuList(props: Props) {
function handleToggleAdminBlock() { function handleToggleAdminBlock() {
if (channelIsAdminBlocked) { if (channelIsAdminBlocked) {
doCommentModUnBlockAsAdmin(channelUri, ''); doCommentModUnBlockAsAdmin(contentChannelUri, '');
} else { } else {
doCommentModBlockAsAdmin(channelUri, ''); doCommentModBlockAsAdmin(contentChannelUri, '');
} }
} }
@ -210,7 +223,7 @@ function ClaimMenuList(props: Props) {
function handleReportContent() { function handleReportContent() {
// $FlowFixMe // $FlowFixMe
push(`/$/${PAGES.REPORT_CONTENT}?claimId=${(repostedContent && repostedContent.claim_id) || claim.claim_id}`); push(`/$/${PAGES.REPORT_CONTENT}?claimId=${contentClaim && contentClaim.claim_id}`);
} }
return ( return (
@ -228,101 +241,79 @@ function ClaimMenuList(props: Props) {
{(!IS_WEB || (IS_WEB && isAuthenticated)) && ( {(!IS_WEB || (IS_WEB && isAuthenticated)) && (
<> <>
<> <>
{/* WATCH LATER */}
{isPlayable && !collectionId && (
<MenuItem
className="comment__menu-option"
onSelect={() => {
doToast({
message: hasClaimInWatchLater
? __('Item removed from Watch Later')
: __('Item added to Watch Later'),
});
doCollectionEdit(COLLECTIONS_CONSTS.WATCH_LATER_ID, {
claims: [contentClaim],
remove: hasClaimInWatchLater,
type: 'playlist',
});
}}
>
<div className="menu__link">
<Icon aria-hidden icon={hasClaimInWatchLater ? ICONS.DELETE : ICONS.TIME} />
{hasClaimInWatchLater ? __('In Watch Later') : __('Watch Later')}
</div>
</MenuItem>
)}
{/* CUSTOM LIST */}
{isPlayable && !collectionId && (
<MenuItem
className="comment__menu-option"
onSelect={() => {
doToast({
message: hasClaimInCustom
? __('Item removed from %lastCollectionName%', { lastCollectionName })
: __('Item added to %lastCollectionName%', { lastCollectionName }),
});
doCollectionEdit(COLLECTIONS_CONSTS.FAVORITES_ID, {
claims: [contentClaim],
remove: hasClaimInCustom,
type: 'playlist',
});
}}
>
<div className="menu__link">
<Icon aria-hidden icon={hasClaimInCustom ? ICONS.DELETE : ICONS.STAR} />
{hasClaimInCustom
? __('In %lastCollectionName%', { lastCollectionName })
: __(`${lastCollectionName}`)}
</div>
</MenuItem>
)}
{/* COLLECTION OPERATIONS */} {/* COLLECTION OPERATIONS */}
{collectionId && collectionName && isCollectionClaim && ( {collectionId && isCollectionClaim ? (
<> <>
{Boolean(editedCollection) && (
<MenuItem
className="comment__menu-option"
onSelect={() => push(`/$/${PAGES.LIST}/${collectionId}?view=edit`)}
>
<div className="menu__link">
<Icon aria-hidden iconColor={'red'} icon={ICONS.PUBLISH} />
{__('Publish')}
</div>
</MenuItem>
)}
<MenuItem className="comment__menu-option" onSelect={() => push(`/$/${PAGES.LIST}/${collectionId}`)}> <MenuItem className="comment__menu-option" onSelect={() => push(`/$/${PAGES.LIST}/${collectionId}`)}>
<div className="menu__link"> <div className="menu__link">
<Icon aria-hidden icon={ICONS.VIEW} /> <Icon aria-hidden icon={ICONS.VIEW} />
{__('View List')} {__('View List')}
</div> </div>
</MenuItem> </MenuItem>
<MenuItem {isMyCollection && (
className="comment__menu-option" <>
onSelect={() => openModal(MODALS.COLLECTION_DELETE, { collectionId })} <MenuItem
> className="comment__menu-option"
<div className="menu__link"> onSelect={() => push(`/$/${PAGES.LIST}/${collectionId}?view=edit`)}
<Icon aria-hidden icon={ICONS.DELETE} /> >
{__('Delete List')} <div className="menu__link">
</div> <Icon aria-hidden iconColor={'red'} icon={ICONS.PUBLISH} />
</MenuItem> {editedCollection ? __('Publish') : __('Edit List')}
</div>
</MenuItem>
<MenuItem
className="comment__menu-option"
onSelect={() => openModal(MODALS.COLLECTION_DELETE, { collectionId })}
>
<div className="menu__link">
<Icon aria-hidden icon={ICONS.DELETE} />
{__('Delete List')}
</div>
</MenuItem>
</>
)}
</> </>
)} ) : (
{/* CURRENTLY ONLY SUPPORT PLAYLISTS FOR PLAYABLE; LATER DIFFERENT TYPES */} isPlayable && (
{isPlayable && ( <>
<MenuItem {/* WATCH LATER */}
className="comment__menu-option" <MenuItem
onSelect={() => openModal(MODALS.COLLECTION_ADD, { uri, type: 'playlist' })} className="comment__menu-option"
> onSelect={() => handleAdd(hasClaimInWatchLater, 'Watch Later', COLLECTIONS_CONSTS.WATCH_LATER_ID)}
<div className="menu__link"> >
<Icon aria-hidden icon={ICONS.STACK} /> <div className="menu__link">
{__('Add to Lists')} <Icon aria-hidden icon={hasClaimInWatchLater ? ICONS.DELETE : ICONS.TIME} />
</div> {hasClaimInWatchLater ? __('In Watch Later') : __('Watch Later')}
</MenuItem> </div>
</MenuItem>
{/* CUSTOM LIST */}
<MenuItem
className="comment__menu-option"
onSelect={() => handleAdd(hasClaimInCustom, lastCollectionName, lastCollectionId)}
>
<div className="menu__link">
<Icon aria-hidden icon={hasClaimInCustom ? ICONS.DELETE : ICONS.STAR} />
{hasClaimInCustom ? __(`In ${lastCollectionName}`) : __(`${lastCollectionName}`)}
</div>
</MenuItem>
{/* CURRENTLY ONLY SUPPORT PLAYLISTS FOR PLAYABLE; LATER DIFFERENT TYPES */}
<MenuItem
className="comment__menu-option"
onSelect={() => openModal(MODALS.COLLECTION_ADD, { uri, type: 'playlist' })}
>
<div className="menu__link">
<Icon aria-hidden icon={ICONS.STACK} />
{__('Add to Lists')}
</div>
</MenuItem>
<hr className="menu__separator" />
</>
)
)} )}
</> </>
{!isChannelPage && ( {!isChannelPage && (
<> <>
<hr className="menu__separator" />
<MenuItem className="comment__menu-option" onSelect={handleSupport}> <MenuItem className="comment__menu-option" onSelect={handleSupport}>
<div className="menu__link"> <div className="menu__link">
<Icon aria-hidden icon={ICONS.LBC} /> <Icon aria-hidden icon={ICONS.LBC} />
@ -332,7 +323,7 @@ function ClaimMenuList(props: Props) {
</> </>
)} )}
{!incognitoClaim && !isRepost && !claimIsMine && !isChannelPage && ( {!incognitoClaim && !claimIsMine && !isChannelPage && (
<> <>
<hr className="menu__separator" /> <hr className="menu__separator" />
<MenuItem className="comment__menu-option" onSelect={handleFollow}> <MenuItem className="comment__menu-option" onSelect={handleFollow}>
@ -343,11 +334,11 @@ function ClaimMenuList(props: Props) {
</MenuItem> </MenuItem>
</> </>
)} )}
{!isMyCollection && ( {!isMyCollection && (
<> <>
{(!claimIsMine || channelIsBlocked) && channelUri ? ( {(!claimIsMine || channelIsBlocked) && contentChannelUri ? (
!incognitoClaim && !incognitoClaim && (
!isRepost && (
<> <>
<hr className="menu__separator" /> <hr className="menu__separator" />
<MenuItem className="comment__menu-option" onSelect={handleToggleBlock}> <MenuItem className="comment__menu-option" onSelect={handleToggleBlock}>
@ -376,7 +367,7 @@ function ClaimMenuList(props: Props) {
) )
) : ( ) : (
<> <>
{!isChannelPage && !isRepost && ( {!isChannelPage && !repostedClaim && (
<MenuItem className="comment__menu-option" onSelect={handleEdit}> <MenuItem className="comment__menu-option" onSelect={handleEdit}>
<div className="menu__link"> <div className="menu__link">
<Icon aria-hidden icon={ICONS.EDIT} /> <Icon aria-hidden icon={ICONS.EDIT} />
@ -384,7 +375,6 @@ function ClaimMenuList(props: Props) {
</div> </div>
</MenuItem> </MenuItem>
)} )}
{showDelete && ( {showDelete && (
<MenuItem className="comment__menu-option" onSelect={handleDelete}> <MenuItem className="comment__menu-option" onSelect={handleDelete}>
<div className="menu__link"> <div className="menu__link">
@ -412,7 +402,7 @@ function ClaimMenuList(props: Props) {
<MenuItem className="comment__menu-option" onSelect={handleCopyLink}> <MenuItem className="comment__menu-option" onSelect={handleCopyLink}>
<div className="menu__link"> <div className="menu__link">
<Icon aria-hidden icon={ICONS.COPY_LINK} /> <Icon aria-hidden icon={ICONS.SHARE} />
{__('Copy Link')} {__('Copy Link')}
</div> </div>
</MenuItem> </MenuItem>

View file

@ -144,12 +144,14 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
collectionUris, collectionUris,
disableNavigation, disableNavigation,
} = props; } = props;
const isRepost = claim && claim.repost_channel_url; const isCollection = claim && claim.value_type === 'collection';
const collectionClaimId = isCollection && claim && claim.claim_id;
const listId = collectionId || collectionClaimId;
const WrapperElement = wrapperElement || 'li'; const WrapperElement = wrapperElement || 'li';
const shouldFetch = const shouldFetch =
claim === undefined || (claim !== null && claim.value_type === 'channel' && isEmpty(claim.meta) && !pending); claim === undefined || (claim !== null && claim.value_type === 'channel' && isEmpty(claim.meta) && !pending);
const abandoned = !isResolvingUri && !claim; const abandoned = !isResolvingUri && !claim;
const isMyCollection = collectionId && (isCollectionMine || collectionId.includes('-')); const isMyCollection = listId && (isCollectionMine || listId.includes('-'));
const shouldHideActions = hideActions || isMyCollection || type === 'small' || type === 'tooltip'; const shouldHideActions = hideActions || isMyCollection || type === 'small' || type === 'tooltip';
const canonicalUrl = claim && claim.canonical_url; const canonicalUrl = claim && claim.canonical_url;
const lastCollectionIndex = collectionUris ? collectionUris.length - 1 : 0; const lastCollectionIndex = collectionUris ? collectionUris.length - 1 : 0;
@ -171,16 +173,14 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
claim.value.stream_type && claim.value.stream_type &&
// $FlowFixMe // $FlowFixMe
(claim.value.stream_type === 'audio' || claim.value.stream_type === 'video'); (claim.value.stream_type === 'audio' || claim.value.stream_type === 'video');
const isCollection = claim && claim.value_type === 'collection';
const isChannelUri = isValid ? parseURI(uri).isChannel : false; const isChannelUri = isValid ? parseURI(uri).isChannel : false;
const signingChannel = claim && claim.signing_channel; const signingChannel = claim && claim.signing_channel;
let navigateUrl = formatLbryUrlForWeb((claim && claim.canonical_url) || uri || '/'); let navigateUrl = formatLbryUrlForWeb((claim && claim.canonical_url) || uri || '/');
if (collectionId) { if (listId) {
const collectionParams = new URLSearchParams(); const collectionParams = new URLSearchParams();
collectionParams.set(COLLECTIONS_CONSTS.COLLECTION_ID, collectionId); collectionParams.set(COLLECTIONS_CONSTS.COLLECTION_ID, listId);
navigateUrl = navigateUrl + `?` + collectionParams.toString(); navigateUrl = navigateUrl + `?` + collectionParams.toString();
} }
const channelUri = !isChannelUri ? signingChannel && signingChannel.permanent_url : claim && claim.permanent_url;
const navLinkProps = { const navLinkProps = {
to: navigateUrl, to: navigateUrl,
onClick: (e) => e.stopPropagation(), onClick: (e) => e.stopPropagation(),
@ -365,7 +365,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
{!pending && ( {!pending && (
<> <>
{renderActions && claim && renderActions(claim)} {renderActions && claim && renderActions(claim)}
{Boolean(isMyCollection && collectionId) && ( {Boolean(isMyCollection && listId) && (
<> <>
<div className="collection-preview__edit-buttons"> <div className="collection-preview__edit-buttons">
<div className="collection-preview__edit-group"> <div className="collection-preview__edit-group">
@ -379,7 +379,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
e.stopPropagation(); e.stopPropagation();
if (editCollection) { if (editCollection) {
// $FlowFixMe // $FlowFixMe
editCollection(collectionId, { editCollection(listId, {
order: { from: collectionIndex, to: Number(collectionIndex) - 1 }, order: { from: collectionIndex, to: Number(collectionIndex) - 1 },
}); });
} }
@ -395,7 +395,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
e.stopPropagation(); e.stopPropagation();
if (editCollection) { if (editCollection) {
// $FlowFixMe // $FlowFixMe
editCollection(collectionId, { editCollection(listId, {
order: { from: collectionIndex, to: Number(collectionIndex + 1) }, order: { from: collectionIndex, to: Number(collectionIndex + 1) },
}); });
} }
@ -410,7 +410,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
// $FlowFixMe // $FlowFixMe
if (editCollection) editCollection(collectionId, { claims: [claim], remove: true }); if (editCollection) editCollection(listId, { claims: [claim], remove: true });
}} }}
/> />
</div> </div>
@ -452,7 +452,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
</div> </div>
</div> </div>
{!hideMenu && ( {!hideMenu && (
<ClaimMenuList uri={uri} collectionId={collectionId} channelUri={channelUri} isRepost={isRepost} /> <ClaimMenuList uri={uri} collectionId={listId} />
)} )}
</> </>
</WrapperElement> </WrapperElement>

View file

@ -236,7 +236,7 @@ function ClaimPreviewTile(props: Props) {
<UriIndicator uri={uri} /> <UriIndicator uri={uri} />
</div> </div>
)} )}
<ClaimMenuList uri={uri} collectionId={listId} channelUri={channelUri} isRepost={isRepost} /> <ClaimMenuList uri={uri} collectionId={listId} />
</h2> </h2>
</NavLink> </NavLink>
<div> <div>

View file

@ -2,15 +2,16 @@ import { connect } from 'react-redux';
import { doDeleteFileAndMaybeGoBack } from 'redux/actions/file'; import { doDeleteFileAndMaybeGoBack } from 'redux/actions/file';
import { import {
makeSelectTitleForUri, makeSelectTitleForUri,
makeSelectClaimIsMine, doResolveUri,
makeSelectClaimForUri, makeSelectClaimForUri,
makeSelectIsAbandoningClaimForUri, makeSelectIsAbandoningClaimForUri,
} from 'lbry-redux'; } from 'lbry-redux';
import { doHideModal } from 'redux/actions/app'; import { doHideModal } from 'redux/actions/app';
import ModalRemoveFile from './view'; import ModalRemoveFile from './view';
import { makeSelectSigningIsMine } from 'redux/selectors/content';
const select = (state, props) => ({ const select = (state, props) => ({
claimIsMine: makeSelectClaimIsMine(props.uri)(state), claimIsMine: makeSelectSigningIsMine(props.uri)(state),
title: makeSelectTitleForUri(props.uri)(state), title: makeSelectTitleForUri(props.uri)(state),
claim: makeSelectClaimForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state),
isAbandoning: makeSelectIsAbandoningClaimForUri(props.uri)(state), isAbandoning: makeSelectIsAbandoningClaimForUri(props.uri)(state),
@ -18,8 +19,9 @@ const select = (state, props) => ({
const perform = dispatch => ({ const perform = dispatch => ({
closeModal: () => dispatch(doHideModal()), closeModal: () => dispatch(doHideModal()),
deleteFile: (uri, deleteFromComputer, abandonClaim) => { doResolveUri: (uri) => dispatch(doResolveUri(uri)),
dispatch(doDeleteFileAndMaybeGoBack(uri, deleteFromComputer, abandonClaim)); deleteFile: (uri, deleteFromComputer, abandonClaim, doGoBack) => {
dispatch(doDeleteFileAndMaybeGoBack(uri, deleteFromComputer, abandonClaim, doGoBack));
}, },
}); });

View file

@ -12,8 +12,10 @@ type Props = {
uri: string, uri: string,
claim: StreamClaim, claim: StreamClaim,
claimIsMine: boolean, claimIsMine: boolean,
doResolveUri: (string) => void,
closeModal: () => void, closeModal: () => void,
deleteFile: (string, boolean, boolean) => void, deleteFile: (string, boolean, boolean, boolean) => void,
doGoBack: boolean,
title: string, title: string,
fileInfo?: { fileInfo?: {
outpoint: ?string, outpoint: ?string,
@ -22,10 +24,16 @@ type Props = {
}; };
function ModalRemoveFile(props: Props) { function ModalRemoveFile(props: Props) {
const { uri, claimIsMine, closeModal, deleteFile, title, claim, isAbandoning } = props; const { uri, claimIsMine, doResolveUri, closeModal, deleteFile, doGoBack = true, title, claim, isAbandoning } = props;
const [deleteChecked, setDeleteChecked] = usePersistedState('modal-remove-file:delete', true); const [deleteChecked, setDeleteChecked] = usePersistedState('modal-remove-file:delete', true);
const [abandonChecked, setAbandonChecked] = usePersistedState('modal-remove-file:abandon', true); const [abandonChecked, setAbandonChecked] = usePersistedState('modal-remove-file:abandon', true);
React.useEffect(() => {
if (uri) {
doResolveUri(uri);
}
}, [uri, doResolveUri]);
return ( return (
<Modal isOpen contentLabel={__('Confirm File Remove')} type="card" onAborted={closeModal}> <Modal isOpen contentLabel={__('Confirm File Remove')} type="card" onAborted={closeModal}>
<Card <Card
@ -53,7 +61,7 @@ function ModalRemoveFile(props: Props) {
name="claim_abandon" name="claim_abandon"
label={ label={
<I18nMessage <I18nMessage
tokens={{ lbc: <LbcSymbol prefix={__('reclaim %amount%', { amount: claim.amount })} /> }} tokens={{ lbc: <LbcSymbol prefix={__('reclaim %amount%', { amount: claim && claim.amount })} /> }}
> >
Remove from blockchain (%lbc%) Remove from blockchain (%lbc%)
</I18nMessage> </I18nMessage>
@ -87,7 +95,7 @@ function ModalRemoveFile(props: Props) {
button="primary" button="primary"
label={isAbandoning ? __('Removing...') : __('OK')} label={isAbandoning ? __('Removing...') : __('OK')}
disabled={isAbandoning || !(deleteChecked || abandonChecked)} disabled={isAbandoning || !(deleteChecked || abandonChecked)}
onClick={() => deleteFile(uri, deleteChecked, claimIsMine ? abandonChecked : false)} onClick={() => deleteFile(uri, deleteChecked, claimIsMine ? abandonChecked : false, doGoBack)}
/> />
<Button button="link" label={__('Cancel')} onClick={closeModal} /> <Button button="link" label={__('Cancel')} onClick={closeModal} />
</div> </div>

View file

@ -218,7 +218,7 @@ function ChannelPage(props: Props) {
{!(isBlocked || isMuted) && <ClaimSupportButton uri={uri} />} {!(isBlocked || isMuted) && <ClaimSupportButton uri={uri} />}
{!(isBlocked || isMuted) && (!channelIsBlackListed || isSubscribed) && <SubscribeButton uri={permanentUrl} />} {!(isBlocked || isMuted) && (!channelIsBlackListed || isSubscribed) && <SubscribeButton uri={permanentUrl} />}
{/* TODO: add channel collections <ClaimCollectionAddButton uri={uri} fileAction /> */} {/* TODO: add channel collections <ClaimCollectionAddButton uri={uri} fileAction /> */}
<ClaimMenuList uri={claim.permanent_url} channelUri={claim.permanent_url} inline isChannelPage /> <ClaimMenuList uri={claim.permanent_url} inline isChannelPage />
</div> </div>
{cover && <img className={classnames('channel-cover__custom')} src={PlaceholderTx} />} {cover && <img className={classnames('channel-cover__custom')} src={PlaceholderTx} />}
{cover && <OptimizedImage className={classnames('channel-cover__custom')} src={cover} objectFit="cover" />} {cover && <OptimizedImage className={classnames('channel-cover__custom')} src={cover} objectFit="cover" />}

View file

@ -24,6 +24,8 @@ import { makeSelectNotificationForCommentId } from 'redux/selectors/notification
import { selectActiveChannelClaim } from 'redux/selectors/app'; import { selectActiveChannelClaim } from 'redux/selectors/app';
import { toHex } from 'util/hex'; import { toHex } from 'util/hex';
import Comments from 'comments'; import Comments from 'comments';
import { selectPrefsReady } from 'redux/selectors/sync';
import { doAlertWaitingForSync } from 'redux/actions/app';
const isDev = process.env.NODE_ENV !== 'production'; const isDev = process.env.NODE_ENV !== 'production';
@ -726,8 +728,22 @@ function doCommentModToggleBlock(
) { ) {
return async (dispatch: Dispatch, getState: GetState) => { return async (dispatch: Dispatch, getState: GetState) => {
const state = getState(); const state = getState();
const ready = selectPrefsReady(state);
let blockerChannelClaims = selectMyChannelClaims(state); let blockerChannelClaims = selectMyChannelClaims(state);
if (!ready) {
return dispatch(doAlertWaitingForSync());
}
if (!blockerChannelClaims) {
return dispatch(
doToast({
message: __('Create a channel to change this setting.'),
isError: false,
})
);
}
if (blockerIds.length === 0) { if (blockerIds.length === 0) {
// Specific blockers not provided, so find one based on block-level. // Specific blockers not provided, so find one based on block-level.
switch (blockLevel) { switch (blockLevel) {

View file

@ -53,7 +53,7 @@ export function doDeleteFile(outpoint, deleteFromComputer, abandonClaim, cb) {
}; };
} }
export function doDeleteFileAndMaybeGoBack(uri, deleteFromComputer, abandonClaim) { export function doDeleteFileAndMaybeGoBack(uri, deleteFromComputer, abandonClaim, doGoBack) {
return (dispatch, getState) => { return (dispatch, getState) => {
const state = getState(); const state = getState();
const playingUri = selectPlayingUri(state); const playingUri = selectPlayingUri(state);
@ -70,7 +70,9 @@ export function doDeleteFileAndMaybeGoBack(uri, deleteFromComputer, abandonClaim
doDeleteFile(outpoint || claimOutpoint, deleteFromComputer, abandonClaim, (abandonState) => { doDeleteFile(outpoint || claimOutpoint, deleteFromComputer, abandonClaim, (abandonState) => {
if (abandonState === ABANDON_STATES.DONE) { if (abandonState === ABANDON_STATES.DONE) {
if (abandonClaim) { if (abandonClaim) {
dispatch(goBack()); if (doGoBack) {
dispatch(goBack());
}
dispatch(doHideModal()); dispatch(doHideModal());
} }
} }