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:
parent
fdca58727c
commit
b164a5d1f4
9 changed files with 175 additions and 149 deletions
|
@ -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)),
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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" />}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue