Use 'selectHasChannel' instead of the full 'selectMyChannelClaims' (#7427)

- selectMyChannelClaims depends on `byId`, which currently is always invalidated per update, so it is not memoized.

- Most of the use-cases just needs the ID or the length of the array anyways, so avoid generating a Claim array (in selectMyChannelClaims) unnecessarily -- the client need to reduce it back down to IDs again :/

- The simpler boolean also removes the need to memoize the selector, which saves a bit of memory.

Co-authored-by: infinite-persistence <inf.persistence@gmail.com>
This commit is contained in:
jessopb 2022-01-21 12:38:11 -05:00 committed by GitHub
parent 2f1fc941bb
commit ca0cd2ca75
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 27 additions and 52 deletions

View file

@ -4,7 +4,6 @@ import {
makeSelectClaimForUri,
selectThumbnailForUri,
selectHasChannels,
selectMyChannelClaims,
} from 'redux/selectors/claims';
import { doCommentUpdate, doCommentList } from 'redux/actions/comments';
import { makeSelectChannelIsMuted } from 'redux/selectors/blocked';
@ -31,8 +30,7 @@ const select = (state, props) => {
commentingEnabled: true,
othersReacts: selectOthersReactsForComment(state, reactionKey),
activeChannelClaim,
hasChannels: selectHasChannels(state), //
myChannels: selectMyChannelClaims(state),
hasChannels: selectHasChannels(state),
playingUri: selectPlayingUri(state),
stakedLevel: selectTotalStakedAmountForChannelUri(state, props.authorUri),
linkedCommentAncestors: selectLinkedCommentAncestors(state),

View file

@ -47,7 +47,7 @@ type Props = {
commentModBlock: (string) => void,
linkedCommentId?: string,
linkedCommentAncestors: { [string]: Array<string> },
myChannels: ?Array<ChannelClaim>,
hasChannels: boolean,
commentingEnabled: boolean,
doToast: ({ message: string }) => void,
isTopLevel?: boolean,
@ -92,7 +92,7 @@ function Comment(props: Props) {
linkedCommentId,
linkedCommentAncestors,
commentingEnabled,
myChannels,
hasChannels,
doToast,
isTopLevel,
threadDepth,
@ -125,7 +125,6 @@ function Comment(props: Props) {
const [page, setPage] = useState(0);
const [advancedEditor] = usePersistedState('comment-editor-mode', false);
const [displayDeadComment, setDisplayDeadComment] = React.useState(false);
const hasChannels = myChannels && myChannels.length > 0;
const likesCount = (othersReacts && othersReacts.like) || 0;
const dislikesCount = (othersReacts && othersReacts.dislike) || 0;
const totalLikesAndDislikes = likesCount + dislikesCount;

View file

@ -27,7 +27,7 @@ type Props = {
fileInfo: FileListItem,
costInfo: ?{ cost: number },
renderMode: string,
myChannels: ?Array<ChannelClaim>,
hasChannels: boolean,
hideRepost?: boolean,
reactionsDisabled: boolean,
download: (string) => void,
@ -44,7 +44,7 @@ function FileActions(props: Props) {
costInfo,
renderMode,
prepareEdit,
myChannels,
hasChannels,
hideRepost,
reactionsDisabled,
} = props;
@ -55,7 +55,6 @@ function FileActions(props: Props) {
const isMobile = useIsMobile();
const webShareable = costInfo && costInfo.cost === 0 && RENDER_MODES.WEB_SHAREABLE_MODES.includes(renderMode);
const showDelete = claimIsMine || (fileInfo && (fileInfo.written_bytes > 0 || fileInfo.blobs_completed > 0));
const hasChannels = myChannels && myChannels.length > 0;
const claimId = claim && claim.claim_id;
const { signing_channel: signingChannel } = claim;
const channelName = signingChannel && signingChannel.name;
@ -84,9 +83,7 @@ function FileActions(props: Props) {
{ENABLE_FILE_REACTIONS && !reactionsDisabled && <FileReactions uri={uri} />}
<ClaimSupportButton uri={uri} fileAction />
<ClaimCollectionAddButton uri={uri} fileAction />
{!hideRepost && (
<ClaimRepostButton uri={uri} claim={claim} hasChannels={hasChannels} />
)}
{!hideRepost && <ClaimRepostButton uri={uri} claim={claim} hasChannels={hasChannels} />}
<Button
className="button--file-action"
icon={ICONS.SHARE}

View file

@ -15,7 +15,6 @@ import {
selectIsResolvingPublishUris,
selectMyClaimForUri,
} from 'redux/selectors/publish';
import { selectMyChannelClaims } from 'redux/selectors/claims';
import * as RENDER_MODES from 'constants/file_render_modes';
import * as SETTINGS from 'constants/settings';
import { doClaimInitialRewards } from 'redux/actions/rewards';
@ -33,7 +32,7 @@ import {
import { makeSelectClientSetting } from 'redux/selectors/settings';
import { makeSelectFileRenderModeForUri } from 'redux/selectors/content';
import { selectUser } from 'redux/selectors/user';
import PublishPage from './view';
import PublishForm from './view';
const select = (state) => {
const myClaimForUri = selectMyClaimForUri(state);
@ -60,7 +59,6 @@ const select = (state) => {
modal: selectModal(state),
enablePublishPreview: makeSelectClientSetting(SETTINGS.ENABLE_PUBLISH_PREVIEW)(state),
activeChannelClaim: selectActiveChannelClaim(state),
myChannels: selectMyChannelClaims(state),
incognito: selectIncognito(state),
activeChannelStakedLevel: selectActiveChannelStakedLevel(state),
isClaimingInitialRewards: selectIsClaimingInitialRewards(state),
@ -79,4 +77,4 @@ const perform = (dispatch) => ({
claimInitialRewards: () => dispatch(doClaimInitialRewards()),
});
export default connect(select, perform)(PublishPage);
export default connect(select, perform)(PublishForm);

View file

@ -3,7 +3,6 @@ import { doHideModal } from 'redux/actions/app';
import {
makeSelectClaimForUri,
selectTitleForUri,
selectMyChannelClaims,
selectRepostError,
selectRepostLoading,
selectMyClaimsWithoutChannels,
@ -24,7 +23,6 @@ import { selectActiveChannelClaim, selectIncognito } from 'redux/selectors/app';
import RepostCreate from './view';
const select = (state, props) => ({
channels: selectMyChannelClaims(state),
claim: makeSelectClaimForUri(props.uri)(state),
passedRepostClaim: makeSelectClaimForUri(props.name, false)(state),
passedRepostAmount: makeSelectEffectiveAmountForUri(props.name)(state),

View file

@ -28,7 +28,6 @@ type Props = {
claim?: StreamClaim,
enteredContentClaim?: StreamClaim,
balance: number,
channels: ?Array<ChannelClaim>,
doCheckPublishNameAvailability: (string) => Promise<*>,
error: ?string,
reposting: boolean,

View file

@ -1,5 +1,5 @@
import { connect } from 'react-redux';
import { selectMyChannelClaims } from 'redux/selectors/claims';
import { selectHasChannels } from 'redux/selectors/claims';
import { selectWalletIsEncrypted } from 'redux/selectors/wallet';
import { doWalletStatus } from 'redux/actions/wallet';
import { selectUser, selectUserVerifiedEmail } from 'redux/selectors/user';
@ -11,7 +11,7 @@ const select = (state) => ({
isAuthenticated: selectUserVerifiedEmail(state),
walletEncrypted: selectWalletIsEncrypted(state),
user: selectUser(state),
myChannels: selectMyChannelClaims(state),
hasChannels: selectHasChannels(state),
language: selectLanguage(state),
});

View file

@ -10,17 +10,15 @@ import SyncToggle from 'component/syncToggle';
import { getPasswordFromCookie } from 'util/saved-passwords';
type Props = {
// --- select ---
isAuthenticated: boolean,
walletEncrypted: boolean,
user: User,
myChannels: ?Array<ChannelClaim>,
// --- perform ---
hasChannels: boolean,
doWalletStatus: () => void,
};
export default function SettingAccount(props: Props) {
const { isAuthenticated, walletEncrypted, myChannels, doWalletStatus } = props;
const { isAuthenticated, walletEncrypted, hasChannels, doWalletStatus } = props;
const [storedPassword, setStoredPassword] = React.useState(false);
// Determine if password is stored.
@ -59,7 +57,7 @@ export default function SettingAccount(props: Props) {
<SyncToggle disabled={walletEncrypted && !storedPassword && storedPassword !== ''} />
{/* @endif */}
{myChannels && (
{hasChannels && (
<SettingsRow title={__('Comments')} subtitle={__('View your past comments.')}>
<Button
button="inverse"

View file

@ -1,6 +1,6 @@
import { connect } from 'react-redux';
import { selectBalance } from 'redux/selectors/wallet';
import { selectMyChannelClaims, makeSelectClaimForUri } from 'redux/selectors/claims';
import { makeSelectClaimForUri } from 'redux/selectors/claims';
import { doOpenModal } from 'redux/actions/app';
import WalletSend from './view';
import { withRouter } from 'react-router';
@ -12,7 +12,6 @@ const perform = (dispatch) => ({
const select = (state, props) => ({
balance: selectBalance(state),
channels: selectMyChannelClaims(state),
contentClaim: makeSelectClaimForUri(props.contentUri)(state),
snack: selectToast(state),
});

View file

@ -1,10 +1,5 @@
import { connect } from 'react-redux';
import {
selectMyChannelClaims,
selectMyChannelUrls,
selectFetchingMyChannels,
makeSelectClaimIsPending,
} from 'redux/selectors/claims';
import { selectMyChannelUrls, selectFetchingMyChannels, makeSelectClaimIsPending } from 'redux/selectors/claims';
import { doFetchChannelListMine } from 'redux/actions/claims';
import { doSetActiveChannel } from 'redux/actions/app';
import { selectYoutubeChannels } from 'redux/selectors/user';
@ -22,7 +17,6 @@ const select = (state) => {
return {
channelUrls,
channels: selectMyChannelClaims(state),
fetchingChannels: selectFetchingMyChannels(state),
youtubeChannels: selectYoutubeChannels(state),
pendingChannels,

View file

@ -14,7 +14,6 @@ import HelpLink from 'component/common/help-link';
import { useHistory } from 'react-router';
type Props = {
channels: Array<ChannelClaim>,
channelUrls: Array<string>,
fetchChannelListMine: () => void,
fetchingChannels: boolean,

View file

@ -1,11 +1,11 @@
import { connect } from 'react-redux';
import { selectMyChannelClaims, selectFetchingMyChannels } from 'redux/selectors/claims';
import { selectHasChannels, selectFetchingMyChannels } from 'redux/selectors/claims';
import { selectActiveChannelClaim } from 'redux/selectors/app';
import { doSetActiveChannel } from 'redux/actions/app';
import CreatorDashboardPage from './view';
const select = (state) => ({
channels: selectMyChannelClaims(state),
hasChannels: selectHasChannels(state),
fetchingChannels: selectFetchingMyChannels(state),
activeChannelClaim: selectActiveChannelClaim(state),
});

View file

@ -9,14 +9,13 @@ import ChannelSelector from 'component/channelSelector';
import Yrbl from 'component/yrbl';
type Props = {
channels: Array<ChannelClaim>,
hasChannels: boolean,
fetchingChannels: boolean,
activeChannelClaim: ?ChannelClaim,
};
export default function CreatorDashboardPage(props: Props) {
const { channels, fetchingChannels, activeChannelClaim } = props;
const hasChannels = channels && channels.length > 0;
const { hasChannels, fetchingChannels, activeChannelClaim } = props;
return (
<Page>

View file

@ -12,7 +12,7 @@ import {
selectModeratorTimeoutMap,
selectPersonalTimeoutMap,
} from 'redux/selectors/comments';
import { selectMyChannelClaims } from 'redux/selectors/claims';
import { selectMyChannelClaimIds } from 'redux/selectors/claims';
import ListBlocked from './view';
const select = (state) => ({
@ -25,7 +25,7 @@ const select = (state) => ({
moderatorTimeoutMap: selectModeratorTimeoutMap(state),
moderatorBlockListDelegatorsMap: selectModeratorBlockListDelegatorsMap(state),
delegatorsById: selectModerationDelegatorsById(state),
myChannelClaims: selectMyChannelClaims(state),
myChannelClaimIds: selectMyChannelClaimIds(state),
fetchingModerationBlockList: selectFetchingModerationBlockList(state),
});

View file

@ -34,7 +34,7 @@ type Props = {
fetchModBlockedList: () => void,
fetchModAmIList: () => void,
delegatorsById: { [string]: { global: boolean, delegators: { name: string, claimId: string } } },
myChannelClaims: ?Array<ChannelClaim>,
myChannelClaimIds: ?Array<string>,
};
function ListBlocked(props: Props) {
@ -51,7 +51,7 @@ function ListBlocked(props: Props) {
fetchModBlockedList,
fetchModAmIList,
delegatorsById,
myChannelClaims,
myChannelClaimIds,
} = props;
const [viewMode, setViewMode] = usePersistedState('blocked-muted:display', VIEW.BLOCKED);
@ -60,14 +60,11 @@ function ListBlocked(props: Props) {
const stringifiedDelegatorsMap = JSON.stringify(delegatorsMap);
const stringifiedLocalDelegatorsMap = JSON.stringify(localDelegatorsMap);
const isAdmin =
myChannelClaims && myChannelClaims.some((c) => delegatorsById[c.claim_id] && delegatorsById[c.claim_id].global);
const isAdmin = myChannelClaimIds && myChannelClaimIds.some((id) => delegatorsById[id] && delegatorsById[id].global);
const isModerator =
myChannelClaims &&
myChannelClaims.some(
(c) => delegatorsById[c.claim_id] && Object.keys(delegatorsById[c.claim_id].delegators).length > 0
);
myChannelClaimIds &&
myChannelClaimIds.some((id) => delegatorsById[id] && Object.keys(delegatorsById[id].delegators).length > 0);
// **************************************************************************
@ -221,7 +218,7 @@ function ListBlocked(props: Props) {
function getRefreshElem() {
return (
myChannelClaims && (
myChannelClaimIds && (
<Button
icon={ICONS.REFRESH}
button="alt"