improve pop up not identifying your own content in some cases
edit option delete option analytics for channel claim support option follow option fix revert subscription actions block actions mute actions block and mute buttons mute menu option lint handle edit channel fix comment mute logic analytics handle delete channel fix claimismine fix rebase
This commit is contained in:
parent
8f423c5ffb
commit
7d3f35b0c5
16 changed files with 331 additions and 129 deletions
|
@ -6,8 +6,8 @@ type Props = {
|
||||||
uri: string,
|
uri: string,
|
||||||
isBlocked: boolean,
|
isBlocked: boolean,
|
||||||
isBlockingOrUnBlocking: boolean,
|
isBlockingOrUnBlocking: boolean,
|
||||||
doCommentModUnBlock: (string) => void,
|
doCommentModUnBlock: (string, boolean) => void,
|
||||||
doCommentModBlock: (string) => void,
|
doCommentModBlock: (string, boolean) => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
function ChannelBlockButton(props: Props) {
|
function ChannelBlockButton(props: Props) {
|
||||||
|
@ -15,9 +15,9 @@ function ChannelBlockButton(props: Props) {
|
||||||
|
|
||||||
function handleClick() {
|
function handleClick() {
|
||||||
if (isBlocked) {
|
if (isBlocked) {
|
||||||
doCommentModUnBlock(uri);
|
doCommentModUnBlock(uri, false);
|
||||||
} else {
|
} else {
|
||||||
doCommentModBlock(uri);
|
doCommentModBlock(uri, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,8 +30,8 @@ function ChannelBlockButton(props: Props) {
|
||||||
? __('Unblocking...')
|
? __('Unblocking...')
|
||||||
: __('Unblock')
|
: __('Unblock')
|
||||||
: isBlockingOrUnBlocking
|
: isBlockingOrUnBlocking
|
||||||
? __('Blocking...')
|
? __('Blocking...')
|
||||||
: __('Block')
|
: __('Block')
|
||||||
}
|
}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { doToggleMuteChannel } from 'redux/actions/blocked';
|
import { doChannelMute, doChannelUnmute } from 'redux/actions/blocked';
|
||||||
import { makeSelectChannelIsMuted } from 'redux/selectors/blocked';
|
import { makeSelectChannelIsMuted } from 'redux/selectors/blocked';
|
||||||
import ChannelMuteButton from './view';
|
import ChannelMuteButton from './view';
|
||||||
|
|
||||||
|
@ -8,5 +8,6 @@ const select = (state, props) => ({
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(select, {
|
export default connect(select, {
|
||||||
doToggleMuteChannel,
|
doChannelMute,
|
||||||
|
doChannelUnmute,
|
||||||
})(ChannelMuteButton);
|
})(ChannelMuteButton);
|
||||||
|
|
|
@ -6,17 +6,26 @@ type Props = {
|
||||||
uri: string,
|
uri: string,
|
||||||
isMuted: boolean,
|
isMuted: boolean,
|
||||||
channelClaim: ?ChannelClaim,
|
channelClaim: ?ChannelClaim,
|
||||||
doToggleMuteChannel: (string) => void,
|
doChannelMute: (string, boolean) => void,
|
||||||
|
doChannelUnmute: (string, boolean) => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
function ChannelBlockButton(props: Props) {
|
function ChannelBlockButton(props: Props) {
|
||||||
const { uri, doToggleMuteChannel, isMuted } = props;
|
const { uri, doChannelMute, doChannelUnmute, isMuted } = props;
|
||||||
|
|
||||||
|
function handleClick() {
|
||||||
|
if (isMuted) {
|
||||||
|
doChannelUnmute(uri, false);
|
||||||
|
} else {
|
||||||
|
doChannelMute(uri, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
button={isMuted ? 'alt' : 'secondary'}
|
button={isMuted ? 'alt' : 'secondary'}
|
||||||
label={isMuted ? __('Unmute') : __('Mute')}
|
label={isMuted ? __('Unmute') : __('Mute')}
|
||||||
onClick={() => doToggleMuteChannel(uri)}
|
onClick={handleClick}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,6 @@ type Props = {
|
||||||
liveLivestreamsFirst?: boolean,
|
liveLivestreamsFirst?: boolean,
|
||||||
livestreamMap?: { [string]: any },
|
livestreamMap?: { [string]: any },
|
||||||
searchOptions?: any,
|
searchOptions?: any,
|
||||||
channelIsMine: boolean,
|
|
||||||
collectionId?: string,
|
collectionId?: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,7 +75,6 @@ export default function ClaimList(props: Props) {
|
||||||
liveLivestreamsFirst,
|
liveLivestreamsFirst,
|
||||||
livestreamMap,
|
livestreamMap,
|
||||||
searchOptions,
|
searchOptions,
|
||||||
channelIsMine,
|
|
||||||
collectionId,
|
collectionId,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
@ -136,7 +134,6 @@ export default function ClaimList(props: Props) {
|
||||||
showHiddenByUser={showHiddenByUser}
|
showHiddenByUser={showHiddenByUser}
|
||||||
properties={renderProperties}
|
properties={renderProperties}
|
||||||
live={resolveLive(index)}
|
live={resolveLive(index)}
|
||||||
channelIsMine={channelIsMine}
|
|
||||||
collectionId={collectionId}
|
collectionId={collectionId}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
|
@ -73,7 +73,6 @@ type Props = {
|
||||||
livestreamMap?: { [string]: any },
|
livestreamMap?: { [string]: any },
|
||||||
hasSource?: boolean,
|
hasSource?: boolean,
|
||||||
isChannel?: boolean,
|
isChannel?: boolean,
|
||||||
channelIsMine?: boolean,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function ClaimListDiscover(props: Props) {
|
function ClaimListDiscover(props: Props) {
|
||||||
|
@ -129,7 +128,6 @@ function ClaimListDiscover(props: Props) {
|
||||||
livestreamMap,
|
livestreamMap,
|
||||||
hasSource,
|
hasSource,
|
||||||
isChannel = false,
|
isChannel = false,
|
||||||
channelIsMine = false,
|
|
||||||
} = props;
|
} = props;
|
||||||
const didNavigateForward = history.action === 'PUSH';
|
const didNavigateForward = history.action === 'PUSH';
|
||||||
const { search } = location;
|
const { search } = location;
|
||||||
|
@ -512,7 +510,6 @@ function ClaimListDiscover(props: Props) {
|
||||||
liveLivestreamsFirst={liveLivestreamsFirst}
|
liveLivestreamsFirst={liveLivestreamsFirst}
|
||||||
livestreamMap={livestreamMap}
|
livestreamMap={livestreamMap}
|
||||||
searchOptions={options}
|
searchOptions={options}
|
||||||
channelIsMine={channelIsMine}
|
|
||||||
/>
|
/>
|
||||||
{loading && (
|
{loading && (
|
||||||
<div className="claim-grid">
|
<div className="claim-grid">
|
||||||
|
|
|
@ -7,16 +7,23 @@ import {
|
||||||
makeSelectNameForCollectionId,
|
makeSelectNameForCollectionId,
|
||||||
makeSelectCollectionIsMine,
|
makeSelectCollectionIsMine,
|
||||||
COLLECTIONS_CONSTS,
|
COLLECTIONS_CONSTS,
|
||||||
|
makeSelectFileInfoForUri,
|
||||||
|
doPrepareEdit,
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import { makeSelectChannelIsMuted } from 'redux/selectors/blocked';
|
import { makeSelectChannelIsMuted } from 'redux/selectors/blocked';
|
||||||
import { doToggleMuteChannel } from 'redux/actions/blocked';
|
import { doChannelMute, doChannelUnmute } from 'redux/actions/blocked';
|
||||||
|
import { doSetActiveChannel, doSetIncognito, doOpenModal } from 'redux/actions/app';
|
||||||
import { doCommentModBlock, doCommentModUnBlock } from 'redux/actions/comments';
|
import { doCommentModBlock, doCommentModUnBlock } from 'redux/actions/comments';
|
||||||
import { makeSelectChannelIsBlocked } from 'redux/selectors/comments';
|
import { makeSelectChannelIsBlocked } from 'redux/selectors/comments';
|
||||||
import { doOpenModal } from 'redux/actions/app';
|
|
||||||
import { doToast } from 'redux/actions/notifications';
|
import { doToast } from 'redux/actions/notifications';
|
||||||
import { makeSelectUserPropForProp } from 'redux/selectors/user';
|
import { makeSelectUserPropForProp } from 'redux/selectors/user';
|
||||||
|
|
||||||
|
import { makeSelectSigningIsMine } from 'redux/selectors/content';
|
||||||
|
import { doChannelSubscribe, doChannelUnsubscribe } from 'redux/actions/subscriptions';
|
||||||
|
import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions';
|
||||||
import ClaimPreview from './view';
|
import ClaimPreview from './view';
|
||||||
import * as USER from 'constants/user';
|
import * as USER from 'constants/user';
|
||||||
|
import fs from 'fs';
|
||||||
|
|
||||||
const select = (state, props) => {
|
const select = (state, props) => {
|
||||||
const claim = makeSelectClaimForUri(props.uri)(state);
|
const claim = makeSelectClaimForUri(props.uri)(state);
|
||||||
|
@ -35,14 +42,31 @@ const select = (state, props) => {
|
||||||
collectionName: makeSelectNameForCollectionId(props.collectionId)(state),
|
collectionName: makeSelectNameForCollectionId(props.collectionId)(state),
|
||||||
isMyCollection: makeSelectCollectionIsMine(props.collectionId)(state),
|
isMyCollection: makeSelectCollectionIsMine(props.collectionId)(state),
|
||||||
hasExperimentalUi: makeSelectUserPropForProp(USER.EXPERIMENTAL_UI)(state),
|
hasExperimentalUi: makeSelectUserPropForProp(USER.EXPERIMENTAL_UI)(state),
|
||||||
|
fileInfo: makeSelectFileInfoForUri(props.uri)(state),
|
||||||
|
isSubscribed: makeSelectIsSubscribed(props.channelUri, true)(state),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(select, {
|
const perform = (dispatch) => ({
|
||||||
doToggleMuteChannel,
|
prepareEdit: (publishData, uri, fileInfo) => {
|
||||||
doCommentModBlock,
|
if (publishData.signing_channel) {
|
||||||
doCommentModUnBlock,
|
dispatch(doSetIncognito(false));
|
||||||
doCollectionEdit,
|
dispatch(doSetActiveChannel(publishData.signing_channel.claim_id));
|
||||||
doOpenModal,
|
} else {
|
||||||
doToast,
|
dispatch(doSetIncognito(true));
|
||||||
})(ClaimPreview);
|
}
|
||||||
|
|
||||||
|
dispatch(doPrepareEdit(publishData, uri, fileInfo, fs));
|
||||||
|
},
|
||||||
|
openModal: (modal, props) => dispatch(doOpenModal(modal, props)),
|
||||||
|
doChannelMute: (channelUri) => dispatch(doChannelMute(channelUri)),
|
||||||
|
doChannelUnmute: (channelUri) => dispatch(doChannelUnmute(channelUri)),
|
||||||
|
doCommentModBlock: (channelUri) => dispatch(doCommentModBlock(channelUri)),
|
||||||
|
doCommentModUnBlock: (channelUri) => dispatch(doCommentModUnBlock(channelUri)),
|
||||||
|
doChannelSubscribe: (subscription) => dispatch(doChannelSubscribe(subscription)),
|
||||||
|
doChannelUnsubscribe: (subscription) => dispatch(doChannelUnsubscribe(subscription)),
|
||||||
|
doCollectionEdit: (id, params) => dispatch(doCollectionEdit(id, params)),
|
||||||
|
doToast: (params) => dispatch(doToast(params)),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(select, perform)(ClaimPreview);
|
||||||
|
|
|
@ -10,54 +10,81 @@ import Icon from 'component/common/icon';
|
||||||
import { generateShareUrl } from 'util/url';
|
import { generateShareUrl } from 'util/url';
|
||||||
import { useHistory } from 'react-router';
|
import { useHistory } from 'react-router';
|
||||||
import { COLLECTIONS_CONSTS } from 'lbry-redux';
|
import { COLLECTIONS_CONSTS } from 'lbry-redux';
|
||||||
|
import { buildURI, parseURI } from 'lbry-redux';
|
||||||
|
|
||||||
const SHARE_DOMAIN = SHARE_DOMAIN_URL || URL;
|
const SHARE_DOMAIN = SHARE_DOMAIN_URL || URL;
|
||||||
|
const PAGE_VIEW_QUERY = `view`;
|
||||||
|
const EDIT_PAGE = 'edit';
|
||||||
|
|
||||||
|
type SubscriptionArgs = {
|
||||||
|
channelName: string,
|
||||||
|
uri: string,
|
||||||
|
notificationsDisabled?: boolean,
|
||||||
|
};
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
uri: string,
|
uri: string,
|
||||||
|
channelUri: string,
|
||||||
claim: ?Claim,
|
claim: ?Claim,
|
||||||
|
openModal: (id: string, {}) => void,
|
||||||
inline?: boolean,
|
inline?: boolean,
|
||||||
claimIsMine: boolean,
|
|
||||||
channelIsMuted: boolean,
|
channelIsMuted: boolean,
|
||||||
channelIsBlocked: boolean,
|
channelIsBlocked: boolean,
|
||||||
doToggleMuteChannel: (string) => void,
|
doChannelMute: (string) => void,
|
||||||
|
doChannelUnmute: (string) => void,
|
||||||
doCommentModBlock: (string) => void,
|
doCommentModBlock: (string) => void,
|
||||||
doCommentModUnBlock: (string) => void,
|
doCommentModUnBlock: (string) => void,
|
||||||
channelIsMine: boolean,
|
|
||||||
isRepost: boolean,
|
isRepost: boolean,
|
||||||
doCollectionEdit: (string, any) => void,
|
doCollectionEdit: (string, any) => void,
|
||||||
hasClaimInWatchLater: boolean,
|
hasClaimInWatchLater: boolean,
|
||||||
doOpenModal: (string, {}) => void,
|
|
||||||
claimInCollection: boolean,
|
claimInCollection: boolean,
|
||||||
collectionName?: string,
|
collectionName?: string,
|
||||||
collectionId: string,
|
collectionId: string,
|
||||||
isMyCollection: boolean,
|
isMyCollection: boolean,
|
||||||
doToast: ({ message: string }) => void,
|
doToast: ({ message: string }) => void,
|
||||||
hasExperimentalUi: boolean,
|
hasExperimentalUi: boolean,
|
||||||
|
claimIsMine: boolean,
|
||||||
|
fileInfo: FileListItem,
|
||||||
|
prepareEdit: ({}, string, {}) => void,
|
||||||
|
isSubscribed: boolean,
|
||||||
|
doChannelSubscribe: (SubscriptionArgs) => void,
|
||||||
|
doChannelUnsubscribe: (SubscriptionArgs) => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
function ClaimMenuList(props: Props) {
|
function ClaimMenuList(props: Props) {
|
||||||
const {
|
const {
|
||||||
uri,
|
uri,
|
||||||
|
channelUri,
|
||||||
claim,
|
claim,
|
||||||
|
openModal,
|
||||||
inline = false,
|
inline = false,
|
||||||
claimIsMine,
|
doChannelMute,
|
||||||
doToggleMuteChannel,
|
doChannelUnmute,
|
||||||
channelIsMuted,
|
channelIsMuted,
|
||||||
channelIsBlocked,
|
channelIsBlocked,
|
||||||
doCommentModBlock,
|
doCommentModBlock,
|
||||||
doCommentModUnBlock,
|
doCommentModUnBlock,
|
||||||
doCollectionEdit,
|
doCollectionEdit,
|
||||||
hasClaimInWatchLater,
|
hasClaimInWatchLater,
|
||||||
doOpenModal,
|
|
||||||
collectionId,
|
collectionId,
|
||||||
collectionName,
|
collectionName,
|
||||||
isMyCollection,
|
isMyCollection,
|
||||||
doToast,
|
doToast,
|
||||||
hasExperimentalUi,
|
hasExperimentalUi,
|
||||||
|
claimIsMine,
|
||||||
|
fileInfo,
|
||||||
|
prepareEdit,
|
||||||
|
isSubscribed,
|
||||||
|
doChannelSubscribe,
|
||||||
|
doChannelUnsubscribe,
|
||||||
} = props;
|
} = props;
|
||||||
|
const incognito = channelUri && !(channelUri.includes('@'));
|
||||||
|
const signingChannel = claim && (claim.signing_channel || claim);
|
||||||
|
const isChannel = !incognito && signingChannel === claim;
|
||||||
|
const showDelete = claimIsMine || (fileInfo && (fileInfo.written_bytes > 0 || fileInfo.blobs_completed > 0));
|
||||||
|
const subscriptionLabel = isSubscribed ? __('Unfollow') : __('Follow');
|
||||||
|
|
||||||
const { push } = useHistory();
|
const { push, replace } = useHistory();
|
||||||
if (!claim) {
|
if (!claim) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -78,8 +105,28 @@ function ClaimMenuList(props: Props) {
|
||||||
// $FlowFixMe
|
// $FlowFixMe
|
||||||
(claim.value.stream_type === 'audio' || claim.value.stream_type === 'video');
|
(claim.value.stream_type === 'audio' || claim.value.stream_type === 'video');
|
||||||
|
|
||||||
|
function handleFollow() {
|
||||||
|
const permanentUrl = signingChannel && signingChannel.permanent_url;
|
||||||
|
const { channelName } = parseURI(permanentUrl);
|
||||||
|
const subscriptionHandler = isSubscribed ? doChannelUnsubscribe : doChannelSubscribe;
|
||||||
|
|
||||||
|
subscriptionHandler({
|
||||||
|
channelName: '@' + channelName,
|
||||||
|
uri: permanentUrl,
|
||||||
|
notificationsDisabled: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleAnalytics() {
|
||||||
|
push(`/$/${PAGES.CREATOR_DASHBOARD}?channel=${encodeURIComponent(signingChannel.canonical_url)}`);
|
||||||
|
}
|
||||||
|
|
||||||
function handleToggleMute() {
|
function handleToggleMute() {
|
||||||
doToggleMuteChannel(channelUri);
|
if (channelIsMuted) {
|
||||||
|
doChannelUnmute(channelUri);
|
||||||
|
} else {
|
||||||
|
doChannelMute(channelUri);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleToggleBlock() {
|
function handleToggleBlock() {
|
||||||
|
@ -90,6 +137,40 @@ function ClaimMenuList(props: Props) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleEdit() {
|
||||||
|
if (!isChannel) {
|
||||||
|
const signingChannelName = signingChannel && signingChannel.name;
|
||||||
|
|
||||||
|
let editUri;
|
||||||
|
const uriObject: { streamName: string, streamClaimId: string, channelName?: string } = {
|
||||||
|
streamName: claim.name,
|
||||||
|
streamClaimId: claim.claim_id,
|
||||||
|
};
|
||||||
|
if (signingChannelName) {
|
||||||
|
uriObject.channelName = signingChannelName;
|
||||||
|
}
|
||||||
|
editUri = buildURI(uriObject);
|
||||||
|
|
||||||
|
push(`/$/${PAGES.UPLOAD}`);
|
||||||
|
prepareEdit(claim, editUri, fileInfo);
|
||||||
|
} else {
|
||||||
|
const channelUrl = claim.name + ':' + claim.claim_id;
|
||||||
|
push(`/${channelUrl}?${PAGE_VIEW_QUERY}=${EDIT_PAGE}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDelete() {
|
||||||
|
if (!isChannel) {
|
||||||
|
openModal(MODALS.CONFIRM_FILE_REMOVE, { uri });
|
||||||
|
} else {
|
||||||
|
openModal(MODALS.CONFIRM_CLAIM_REVOKE, { claim: claim, cb: () => replace(`/$/${PAGES.CHANNELS}`) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSupport() {
|
||||||
|
openModal(MODALS.SEND_TIP, { uri, isSupport: true });
|
||||||
|
}
|
||||||
|
|
||||||
function handleCopyLink() {
|
function handleCopyLink() {
|
||||||
navigator.clipboard.writeText(shareUrl);
|
navigator.clipboard.writeText(shareUrl);
|
||||||
}
|
}
|
||||||
|
@ -172,7 +253,29 @@ function ClaimMenuList(props: Props) {
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<hr className="menu__separator" />
|
<hr className="menu__separator" />
|
||||||
{channelUri && !claimIsMine && !isMyCollection && (
|
{!incognito && (!claimIsMine ? (
|
||||||
|
<MenuItem className="comment__menu-option" onSelect={handleFollow}>
|
||||||
|
<div className="menu__link">
|
||||||
|
<Icon aria-hidden icon={ICONS.SUBSCRIBE} />
|
||||||
|
{subscriptionLabel}
|
||||||
|
</div>
|
||||||
|
</MenuItem>
|
||||||
|
) : (
|
||||||
|
<MenuItem className="comment__menu-option" onSelect={handleAnalytics}>
|
||||||
|
<div className="menu__link">
|
||||||
|
<Icon aria-hidden icon={ICONS.ANALYTICS} />
|
||||||
|
{__('Channel Analytics')}
|
||||||
|
</div>
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
|
||||||
|
<MenuItem className="comment__menu-option" onSelect={handleSupport}>
|
||||||
|
<div className="menu__link">
|
||||||
|
<Icon aria-hidden icon={ICONS.LBC} />
|
||||||
|
{__('Support')}
|
||||||
|
</div>
|
||||||
|
</MenuItem>
|
||||||
|
{channelUri && !claimIsMine && !isMyCollection && !incognito ? (
|
||||||
<>
|
<>
|
||||||
<MenuItem className="comment__menu-option" onSelect={handleToggleBlock}>
|
<MenuItem className="comment__menu-option" onSelect={handleToggleBlock}>
|
||||||
<div className="menu__link">
|
<div className="menu__link">
|
||||||
|
@ -187,10 +290,27 @@ function ClaimMenuList(props: Props) {
|
||||||
{channelIsMuted ? __('Unmute Channel') : __('Mute Channel')}
|
{channelIsMuted ? __('Unmute Channel') : __('Mute Channel')}
|
||||||
</div>
|
</div>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<MenuItem className="comment__menu-option" onSelect={handleEdit}>
|
||||||
|
<div className="menu__link">
|
||||||
|
<Icon aria-hidden icon={ICONS.EDIT} />
|
||||||
|
{__('Edit')}
|
||||||
|
</div>
|
||||||
|
</MenuItem>
|
||||||
|
|
||||||
<hr className="menu__separator" />
|
{showDelete && (
|
||||||
|
<MenuItem className="comment__menu-option" onSelect={handleDelete}>
|
||||||
|
<div className="menu__link">
|
||||||
|
<Icon aria-hidden icon={ICONS.DELETE} />
|
||||||
|
{__('Delete')}
|
||||||
|
</div>
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
<hr className="menu__separator" />
|
||||||
|
|
||||||
<MenuItem className="comment__menu-option" onSelect={handleCopyLink}>
|
<MenuItem className="comment__menu-option" onSelect={handleCopyLink}>
|
||||||
<div className="menu__link">
|
<div className="menu__link">
|
||||||
|
|
|
@ -30,7 +30,7 @@ import * as ICONS from 'constants/icons';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
uri: string,
|
uri: string,
|
||||||
claim: ?Claim, // maybe?
|
claim: ?Claim,
|
||||||
obscureNsfw: boolean,
|
obscureNsfw: boolean,
|
||||||
showUserBlocked: boolean,
|
showUserBlocked: boolean,
|
||||||
claimIsMine: boolean,
|
claimIsMine: boolean,
|
||||||
|
@ -155,6 +155,8 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
||||||
const isCollection = claim && claim.value_type === 'collection';
|
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;
|
||||||
|
const channelUri = claim && (signingChannel ? signingChannel.permanent_url : claim.permanent_url);
|
||||||
|
|
||||||
let navigateUrl = formatLbryUrlForWeb((claim && claim.canonical_url) || uri || '/');
|
let navigateUrl = formatLbryUrlForWeb((claim && claim.canonical_url) || uri || '/');
|
||||||
if (collectionId) {
|
if (collectionId) {
|
||||||
const collectionParams = new URLSearchParams();
|
const collectionParams = new URLSearchParams();
|
||||||
|
@ -421,7 +423,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{!hideMenu && <ClaimMenuList uri={uri} collectionId={collectionId} />}
|
{!hideMenu && <ClaimMenuList uri={uri} collectionId={collectionId} channelUri={channelUri} />}
|
||||||
</>
|
</>
|
||||||
</WrapperElement>
|
</WrapperElement>
|
||||||
);
|
);
|
||||||
|
|
|
@ -43,7 +43,6 @@ type Props = {
|
||||||
showHiddenByUser?: boolean,
|
showHiddenByUser?: boolean,
|
||||||
properties?: (Claim) => void,
|
properties?: (Claim) => void,
|
||||||
live?: boolean,
|
live?: boolean,
|
||||||
channelIsMine?: boolean,
|
|
||||||
collectionId?: string,
|
collectionId?: string,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,7 +66,6 @@ function ClaimPreviewTile(props: Props) {
|
||||||
showHiddenByUser,
|
showHiddenByUser,
|
||||||
properties,
|
properties,
|
||||||
live,
|
live,
|
||||||
channelIsMine,
|
|
||||||
collectionId,
|
collectionId,
|
||||||
} = props;
|
} = props;
|
||||||
const isRepost = claim && claim.repost_channel_url;
|
const isRepost = claim && claim.repost_channel_url;
|
||||||
|
@ -100,11 +98,8 @@ function ClaimPreviewTile(props: Props) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let channelUri;
|
|
||||||
const signingChannel = claim && claim.signing_channel;
|
const signingChannel = claim && claim.signing_channel;
|
||||||
if (signingChannel) {
|
const channelUri = signingChannel && signingChannel.permanent_url;
|
||||||
channelUri = signingChannel.permanent_url;
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleClick(e) {
|
function handleClick(e) {
|
||||||
if (navigateUrl) {
|
if (navigateUrl) {
|
||||||
|
@ -219,7 +214,7 @@ function ClaimPreviewTile(props: Props) {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{/* CHECK CLAIM MENU LIST PARAMS (IS REPOST?) */}
|
{/* CHECK CLAIM MENU LIST PARAMS (IS REPOST?) */}
|
||||||
<ClaimMenuList uri={uri} collectionId={listId} channelIsMine={channelIsMine} isRepost={isRepost} />
|
<ClaimMenuList uri={uri} collectionId={listId} channelUri={channelUri} isRepost={isRepost} />
|
||||||
</h2>
|
</h2>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { makeSelectChannelPermUrlForClaimUri, makeSelectClaimIsMine, makeSelectClaimForUri } from 'lbry-redux';
|
import { makeSelectChannelPermUrlForClaimUri, makeSelectClaimIsMine, makeSelectClaimForUri } from 'lbry-redux';
|
||||||
import { doCommentAbandon, doCommentPin, doCommentList, doCommentModBlock } from 'redux/actions/comments';
|
import { doCommentAbandon, doCommentPin, doCommentList, doCommentModBlock } from 'redux/actions/comments';
|
||||||
import { doToggleMuteChannel } from 'redux/actions/blocked';
|
import { doChannelMute } from 'redux/actions/blocked';
|
||||||
// import { doSetActiveChannel } from 'redux/actions/app';
|
// import { doSetActiveChannel } 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';
|
||||||
|
@ -19,7 +19,7 @@ const select = (state, props) => ({
|
||||||
const perform = (dispatch) => ({
|
const perform = (dispatch) => ({
|
||||||
clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })),
|
clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })),
|
||||||
deleteComment: (commentId, creatorChannelUrl) => dispatch(doCommentAbandon(commentId, creatorChannelUrl)),
|
deleteComment: (commentId, creatorChannelUrl) => dispatch(doCommentAbandon(commentId, creatorChannelUrl)),
|
||||||
blockChannel: (channelUri) => dispatch(doToggleMuteChannel(channelUri)),
|
muteChannel: (channelUri) => dispatch(doChannelMute(channelUri)),
|
||||||
pinComment: (commentId, remove) => dispatch(doCommentPin(commentId, remove)),
|
pinComment: (commentId, remove) => dispatch(doCommentPin(commentId, remove)),
|
||||||
fetchComments: (uri) => dispatch(doCommentList(uri)),
|
fetchComments: (uri) => dispatch(doCommentList(uri)),
|
||||||
// setActiveChannel: channelId => dispatch(doSetActiveChannel(channelId)),
|
// setActiveChannel: channelId => dispatch(doSetActiveChannel(channelId)),
|
||||||
|
|
|
@ -15,7 +15,7 @@ type Props = {
|
||||||
linkedComment?: any,
|
linkedComment?: any,
|
||||||
isPinned: boolean,
|
isPinned: boolean,
|
||||||
pinComment: (string, boolean) => Promise<any>,
|
pinComment: (string, boolean) => Promise<any>,
|
||||||
blockChannel: (string) => void,
|
muteChannel: (string) => void,
|
||||||
fetchComments: (string) => void,
|
fetchComments: (string) => void,
|
||||||
handleEditComment: () => void,
|
handleEditComment: () => void,
|
||||||
contentChannelPermanentUrl: any,
|
contentChannelPermanentUrl: any,
|
||||||
|
@ -34,7 +34,7 @@ function CommentMenuList(props: Props) {
|
||||||
commentIsMine,
|
commentIsMine,
|
||||||
commentId,
|
commentId,
|
||||||
deleteComment,
|
deleteComment,
|
||||||
blockChannel,
|
muteChannel,
|
||||||
pinComment,
|
pinComment,
|
||||||
clearPlayingUri,
|
clearPlayingUri,
|
||||||
activeChannelClaim,
|
activeChannelClaim,
|
||||||
|
@ -66,7 +66,7 @@ function CommentMenuList(props: Props) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCommentMute() {
|
function handleCommentMute() {
|
||||||
blockChannel(authorUri);
|
muteChannel(authorUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -186,7 +186,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} inline />
|
<ClaimMenuList uri={claim.permanent_url} channelUri={claim.permanent_url} inline />
|
||||||
</div>
|
</div>
|
||||||
{cover && <img className={classnames('channel-cover__custom')} src={cover} />}
|
{cover && <img className={classnames('channel-cover__custom')} src={cover} />}
|
||||||
<div className="channel__primary-info">
|
<div className="channel__primary-info">
|
||||||
|
|
|
@ -2,19 +2,40 @@
|
||||||
import * as ACTIONS from 'constants/action_types';
|
import * as ACTIONS from 'constants/action_types';
|
||||||
import { selectPrefsReady } from 'redux/selectors/sync';
|
import { selectPrefsReady } from 'redux/selectors/sync';
|
||||||
import { doAlertWaitingForSync } from 'redux/actions/app';
|
import { doAlertWaitingForSync } from 'redux/actions/app';
|
||||||
|
import { doToast } from 'redux/actions/notifications';
|
||||||
|
|
||||||
export const doToggleMuteChannel = (uri: string) => (dispatch: Dispatch, getState: GetState) => {
|
export function doToggleMuteChannel(uri: string, showLink: boolean, unmute: boolean = false) {
|
||||||
const state = getState();
|
return async (dispatch: Dispatch, getState: GetState) => {
|
||||||
const ready = selectPrefsReady(state);
|
const state = getState();
|
||||||
|
const ready = selectPrefsReady(state);
|
||||||
|
|
||||||
if (!ready) {
|
if (!ready) {
|
||||||
return dispatch(doAlertWaitingForSync());
|
return dispatch(doAlertWaitingForSync());
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: ACTIONS.TOGGLE_BLOCK_CHANNEL,
|
type: ACTIONS.TOGGLE_BLOCK_CHANNEL,
|
||||||
data: {
|
data: {
|
||||||
uri,
|
uri,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
dispatch(doToast({
|
||||||
|
message: __(!unmute ? 'Channel muted. You will not see them again.' : 'Channel unmuted!'),
|
||||||
|
linkText: __(showLink ? 'See All' : ''),
|
||||||
|
linkTarget: '/settings/block_and_mute',
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doChannelMute(uri: string, showLink: boolean = true) {
|
||||||
|
return (dispatch: Dispatch) => {
|
||||||
|
return dispatch(doToggleMuteChannel(uri, showLink));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doChannelUnmute(uri: string, showLink: boolean = true) {
|
||||||
|
return (dispatch: Dispatch) => {
|
||||||
|
return dispatch(doToggleMuteChannel(uri, showLink, true));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -506,7 +506,7 @@ async function channelSignName(channelClaimId: string, channelName: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hides a users comments from all creator's claims and prevent them from commenting in the future
|
// Hides a users comments from all creator's claims and prevent them from commenting in the future
|
||||||
export function doCommentModToggleBlock(channelUri: string, unblock: boolean = false) {
|
export function doCommentModToggleBlock(channelUri: string, showLink: boolean, unblock: boolean = false) {
|
||||||
return async (dispatch: Dispatch, getState: GetState) => {
|
return async (dispatch: Dispatch, getState: GetState) => {
|
||||||
const state = getState();
|
const state = getState();
|
||||||
const myChannels = selectMyChannelClaims(state);
|
const myChannels = selectMyChannelClaims(state);
|
||||||
|
@ -564,9 +564,15 @@ export function doCommentModToggleBlock(channelUri: string, unblock: boolean = f
|
||||||
data: { channelUri },
|
data: { channelUri },
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!unblock) {
|
dispatch(
|
||||||
dispatch(doToast({ message: __('Channel blocked. You will not see them again.') }));
|
doToast({
|
||||||
}
|
message: __(
|
||||||
|
!unblock ? 'Channel blocked. They will not interact with you again.' : 'Channel unblocked!'
|
||||||
|
),
|
||||||
|
linkText: __(showLink ? 'See All' : ''),
|
||||||
|
linkTarget: '/settings/block_and_mute',
|
||||||
|
})
|
||||||
|
);
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
dispatch({
|
dispatch({
|
||||||
|
@ -582,15 +588,15 @@ export function doCommentModToggleBlock(channelUri: string, unblock: boolean = f
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doCommentModBlock(commentAuthor: string) {
|
export function doCommentModBlock(commentAuthor: string, showLink: boolean = true) {
|
||||||
return (dispatch: Dispatch) => {
|
return (dispatch: Dispatch) => {
|
||||||
return dispatch(doCommentModToggleBlock(commentAuthor));
|
return dispatch(doCommentModToggleBlock(commentAuthor, showLink));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function doCommentModUnBlock(commentAuthor: string) {
|
export function doCommentModUnBlock(commentAuthor: string, showLink: boolean = true) {
|
||||||
return (dispatch: Dispatch) => {
|
return (dispatch: Dispatch) => {
|
||||||
return dispatch(doCommentModToggleBlock(commentAuthor, true));
|
return dispatch(doCommentModToggleBlock(commentAuthor, showLink, true));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,69 +1,78 @@
|
||||||
|
// @flow
|
||||||
import * as ACTIONS from 'constants/action_types';
|
import * as ACTIONS from 'constants/action_types';
|
||||||
import REWARDS from 'rewards';
|
import REWARDS from 'rewards';
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
import { doClaimRewardType } from 'redux/actions/rewards';
|
import { doClaimRewardType } from 'redux/actions/rewards';
|
||||||
import { parseURI } from 'lbry-redux';
|
import { parseURI } from 'lbry-redux';
|
||||||
import { doAlertWaitingForSync } from 'redux/actions/app';
|
import { doAlertWaitingForSync } from 'redux/actions/app';
|
||||||
|
import { doToast } from 'redux/actions/notifications';
|
||||||
|
|
||||||
export const doChannelSubscribe = subscription => (dispatch, getState) => {
|
type SubscriptionArgs = {
|
||||||
const {
|
channelName: string,
|
||||||
settings: { daemonSettings },
|
uri: string,
|
||||||
sync: { prefsReady: ready },
|
notificationsDisabled?: boolean,
|
||||||
} = getState();
|
|
||||||
|
|
||||||
if (!ready) {
|
|
||||||
return dispatch(doAlertWaitingForSync());
|
|
||||||
}
|
|
||||||
|
|
||||||
const { share_usage_data: shareSetting } = daemonSettings;
|
|
||||||
const isSharingData = shareSetting || IS_WEB;
|
|
||||||
|
|
||||||
const subscriptionUri = subscription.uri;
|
|
||||||
if (!subscriptionUri.startsWith('lbry://')) {
|
|
||||||
throw Error(`Subscription uris must include the "lbry://" prefix.\nTried to subscribe to ${subscriptionUri}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch({
|
|
||||||
type: ACTIONS.CHANNEL_SUBSCRIBE,
|
|
||||||
data: subscription,
|
|
||||||
});
|
|
||||||
|
|
||||||
// if the user isn't sharing data, keep the subscriptions entirely in the app
|
|
||||||
if (isSharingData || IS_WEB) {
|
|
||||||
const { channelClaimId } = parseURI(subscription.uri);
|
|
||||||
// They are sharing data, we can store their subscriptions in our internal database
|
|
||||||
Lbryio.call('subscription', 'new', {
|
|
||||||
channel_name: subscription.channelName,
|
|
||||||
claim_id: channelClaimId,
|
|
||||||
notifications_disabled: subscription.notificationsDisabled,
|
|
||||||
});
|
|
||||||
|
|
||||||
dispatch(doClaimRewardType(REWARDS.TYPE_SUBSCRIPTION, { failSilently: true }));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const doChannelUnsubscribe = subscription => (dispatch, getState) => {
|
export function doToggleSubscription(subscription: SubscriptionArgs, isSubscribed: boolean = false) {
|
||||||
const {
|
return async (dispatch: Dispatch, getState: GetState) => {
|
||||||
settings: { daemonSettings },
|
const {
|
||||||
sync: { prefsReady: ready },
|
settings: { daemonSettings },
|
||||||
} = getState();
|
sync: { prefsReady: ready },
|
||||||
|
} = getState();
|
||||||
|
|
||||||
if (!ready) {
|
if (!ready) {
|
||||||
return dispatch(doAlertWaitingForSync());
|
return dispatch(doAlertWaitingForSync());
|
||||||
}
|
}
|
||||||
|
|
||||||
const { share_usage_data: shareSetting } = daemonSettings;
|
const { share_usage_data: shareSetting } = daemonSettings;
|
||||||
const isSharingData = shareSetting || IS_WEB;
|
const isSharingData = shareSetting || IS_WEB;
|
||||||
|
|
||||||
dispatch({
|
if (!isSubscribed) {
|
||||||
type: ACTIONS.CHANNEL_UNSUBSCRIBE,
|
const subscriptionUri = subscription.uri;
|
||||||
data: subscription,
|
if (!subscriptionUri.startsWith('lbry://')) {
|
||||||
});
|
throw Error(`Subscription uris must include the "lbry://" prefix.\nTried to subscribe to ${subscriptionUri}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isSharingData) {
|
dispatch({
|
||||||
const { channelClaimId } = parseURI(subscription.uri);
|
type: !isSubscribed ? ACTIONS.CHANNEL_SUBSCRIBE : ACTIONS.CHANNEL_UNSUBSCRIBE,
|
||||||
Lbryio.call('subscription', 'delete', {
|
data: subscription,
|
||||||
claim_id: channelClaimId,
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
};
|
// if the user isn't sharing data, keep the subscriptions entirely in the app
|
||||||
|
if (isSharingData || IS_WEB) {
|
||||||
|
const { channelClaimId } = parseURI(subscription.uri);
|
||||||
|
|
||||||
|
if (!isSubscribed) {
|
||||||
|
// They are sharing data, we can store their subscriptions in our internal database
|
||||||
|
Lbryio.call('subscription', 'new', {
|
||||||
|
channel_name: subscription.channelName,
|
||||||
|
claim_id: channelClaimId,
|
||||||
|
notifications_disabled: subscription.notificationsDisabled,
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatch(doClaimRewardType(REWARDS.TYPE_SUBSCRIPTION, { failSilently: true }));
|
||||||
|
} else {
|
||||||
|
Lbryio.call('subscription', 'delete', {
|
||||||
|
claim_id: channelClaimId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch(doToast({
|
||||||
|
message: __(!isSubscribed ? 'You followed %CHANNEL_NAME%!' : 'Unfollowed %CHANNEL_NAME%.', { CHANNEL_NAME: subscription.channelName }),
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doChannelSubscribe(subscription: SubscriptionArgs) {
|
||||||
|
return (dispatch: Dispatch) => {
|
||||||
|
return dispatch(doToggleSubscription(subscription));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function doChannelUnsubscribe(subscription: SubscriptionArgs) {
|
||||||
|
return (dispatch: Dispatch) => {
|
||||||
|
return dispatch(doToggleSubscription(subscription, true));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ import {
|
||||||
parseURI,
|
parseURI,
|
||||||
makeSelectContentTypeForUri,
|
makeSelectContentTypeForUri,
|
||||||
makeSelectFileNameForUri,
|
makeSelectFileNameForUri,
|
||||||
|
normalizeURI,
|
||||||
|
selectMyActiveClaims,
|
||||||
} from 'lbry-redux';
|
} from 'lbry-redux';
|
||||||
import { makeSelectRecommendedContentForUri } from 'redux/selectors/search';
|
import { makeSelectRecommendedContentForUri } from 'redux/selectors/search';
|
||||||
import { selectMutedChannels } from 'redux/selectors/blocked';
|
import { selectMutedChannels } from 'redux/selectors/blocked';
|
||||||
|
@ -243,3 +245,22 @@ export const makeSelectInsufficientCreditsForUri = (uri: string) =>
|
||||||
return !isMine && costInfo && costInfo.cost > 0 && costInfo.cost > balance;
|
return !isMine && costInfo && costInfo.cost > 0 && costInfo.cost > balance;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const makeSelectSigningIsMine = (rawUri: string) => {
|
||||||
|
let uri;
|
||||||
|
try {
|
||||||
|
uri = normalizeURI(rawUri);
|
||||||
|
} catch (e) { }
|
||||||
|
|
||||||
|
return createSelector(selectClaimsByUri, selectMyActiveClaims, (claims, myClaims) => {
|
||||||
|
try {
|
||||||
|
parseURI(uri);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const repostedChannel = claims && claims[uri] && claims[uri].reposted_claim && (claims[uri].reposted_claim.signing_channel || claims[uri].reposted_claim);
|
||||||
|
const signingChannel = claims && claims[uri] && (repostedChannel || claims[uri].signing_channel || claims[uri]);
|
||||||
|
|
||||||
|
return signingChannel && myClaims.has(signingChannel.claim_id);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue