diff --git a/extras/lbryinc/index.js b/extras/lbryinc/index.js
index 1b23baae0..2d86de5fd 100644
--- a/extras/lbryinc/index.js
+++ b/extras/lbryinc/index.js
@@ -50,9 +50,12 @@ export {
 export { selectFilteredOutpoints, selectFilteredOutpointMap } from './redux/selectors/filtered';
 export {
   selectViewCount,
-  makeSelectViewCountForUri,
-  makeSelectSubCountForUri,
+  selectViewCountForUri,
+  // makeSelectViewCountForUri, // deprecated
+  selectSubCountForUri,
+  // makeSelectSubCountForUri, // deprecated
 } from './redux/selectors/stats';
+export { selectBanStateForUri } from './redux/selectors/ban';
 export {
   selectHasSyncedWallet,
   selectSyncData,
diff --git a/extras/lbryinc/redux/selectors/ban.js b/extras/lbryinc/redux/selectors/ban.js
new file mode 100644
index 000000000..ee0e2b0a0
--- /dev/null
+++ b/extras/lbryinc/redux/selectors/ban.js
@@ -0,0 +1,68 @@
+// @flow
+
+// TODO: This should be in 'redux/selectors/claim.js'. Temporarily putting it
+// here to get past importing issues with 'lbryinc', which the real fix might
+// involve moving it from 'extras' to 'ui' (big change).
+
+import { createCachedSelector } from 're-reselect';
+import { selectClaimForUri } from 'redux/selectors/claims';
+import { selectMutedChannels } from 'redux/selectors/blocked';
+import { selectModerationBlockList } from 'redux/selectors/comments';
+import { selectBlacklistedOutpointMap, selectFilteredOutpointMap } from 'lbryinc';
+import { getChannelFromClaim } from 'util/claim';
+import { isURIEqual } from 'util/lbryURI';
+
+export const selectBanStateForUri = createCachedSelector(
+  selectClaimForUri,
+  selectBlacklistedOutpointMap,
+  selectFilteredOutpointMap,
+  selectMutedChannels,
+  selectModerationBlockList,
+  (claim, blackListedOutpointMap, filteredOutpointMap, mutedChannelUris, personalBlocklist) => {
+    const banState = {};
+
+    if (!claim) {
+      return banState;
+    }
+
+    const channelClaim = getChannelFromClaim(claim);
+
+    // This will be replaced once blocking is done at the wallet server level.
+    if (blackListedOutpointMap) {
+      if (
+        (channelClaim && blackListedOutpointMap[`${channelClaim.txid}:${channelClaim.nout}`]) ||
+        blackListedOutpointMap[`${claim.txid}:${claim.nout}`]
+      ) {
+        banState['blacklisted'] = true;
+      }
+    }
+
+    // We're checking to see if the stream outpoint or signing channel outpoint
+    // is in the filter list.
+    if (filteredOutpointMap) {
+      if (
+        (channelClaim && filteredOutpointMap[`${channelClaim.txid}:${channelClaim.nout}`]) ||
+        filteredOutpointMap[`${claim.txid}:${claim.nout}`]
+      ) {
+        banState['filtered'] = true;
+      }
+    }
+
+    // block stream claims
+    // block channel claims if we can't control for them in claim search
+    if (mutedChannelUris.length && channelClaim) {
+      if (mutedChannelUris.some((blockedUri) => isURIEqual(blockedUri, channelClaim.permanent_url))) {
+        banState['muted'] = true;
+      }
+    }
+
+    // Commentron blocklist
+    if (personalBlocklist.length && channelClaim) {
+      if (personalBlocklist.some((blockedUri) => isURIEqual(blockedUri, channelClaim.permanent_url))) {
+        banState['blocked'] = true;
+      }
+    }
+
+    return banState;
+  }
+)((state, uri) => String(uri));
diff --git a/extras/lbryinc/redux/selectors/stats.js b/extras/lbryinc/redux/selectors/stats.js
index 2b2065285..755402c07 100644
--- a/extras/lbryinc/redux/selectors/stats.js
+++ b/extras/lbryinc/redux/selectors/stats.js
@@ -1,20 +1,20 @@
+// @flow
 import { createSelector } from 'reselect';
-import { makeSelectClaimForUri } from 'redux/selectors/claims';
+import { selectClaimIdForUri } from 'redux/selectors/claims';
 
+type State = { claims: any };
 const selectState = state => state.stats || {};
 export const selectViewCount = createSelector(selectState, state => state.viewCountById);
 export const selectSubCount = createSelector(selectState, state => state.subCountById);
 
-export const makeSelectViewCountForUri = uri =>
-  createSelector(
-    makeSelectClaimForUri(uri),
-    selectViewCount,
-    (claim, viewCountById) => (claim ? viewCountById[claim.claim_id] || 0 : 0)
-  );
+export const selectViewCountForUri = (state: State, uri: string) => {
+  const claimId = selectClaimIdForUri(state, uri);
+  const viewCountById = selectViewCount(state);
+  return claimId ? viewCountById[claimId] || 0 : 0;
+};
 
-export const makeSelectSubCountForUri = uri =>
-  createSelector(
-    makeSelectClaimForUri(uri),
-    selectSubCount,
-    (claim, subCountById) => (claim ? subCountById[claim.claim_id] || 0 : 0)
-  );
+export const selectSubCountForUri = (state: State, uri: string) => {
+  const claimId = selectClaimIdForUri(state, uri);
+  const subCountById = selectSubCount(state);
+  return claimId ? subCountById[claimId] || 0 : 0;
+};
diff --git a/static/app-strings.json b/static/app-strings.json
index 515bb7550..0d2718541 100644
--- a/static/app-strings.json
+++ b/static/app-strings.json
@@ -2235,5 +2235,8 @@
   "Network Data Hosting allows the p2p network to store blobs unrelated to your browsing.": "Network Data Hosting allows the p2p network to store blobs unrelated to your browsing.",
   "Content: Limit (GB)": "Content: Limit (GB)",
   "Network: Allow (GB)": "Network: Allow (GB)",
+  "Failed to view lbry://@Destiny#6/destiny-crashes-conservative-panel-w#a, please try again. If this problem persists, visit https://lbry.com/faq/support for support.": "Failed to view lbry://@Destiny#6/destiny-crashes-conservative-panel-w#a, please try again. If this problem persists, visit https://lbry.com/faq/support for support.",
+  "A channel is required to repost on LBRY": "A channel is required to repost on LBRY",
+  "Failed to view lbry://@gatogalactico#9/gato-galactico-e-as-estrelas-ninja-dos#1, please try again. If this problem persists, visit https://lbry.com/faq/support for support.": "Failed to view lbry://@gatogalactico#9/gato-galactico-e-as-estrelas-ninja-dos#1, please try again. If this problem persists, visit https://lbry.com/faq/support for support.",
   "--end--": "--end--"
 }
diff --git a/ui/component/channelBlockButton/index.js b/ui/component/channelBlockButton/index.js
index 9852404d7..4018ebcc6 100644
--- a/ui/component/channelBlockButton/index.js
+++ b/ui/component/channelBlockButton/index.js
@@ -1,5 +1,5 @@
 import { connect } from 'react-redux';
-import { makeSelectClaimIdForUri } from 'redux/selectors/claims';
+import { selectClaimIdForUri } from 'redux/selectors/claims';
 import {
   doCommentModUnBlock,
   doCommentModBlock,
@@ -43,7 +43,7 @@ const select = (state, props) => {
     isBlocked,
     isToggling,
     isBlockingOrUnBlocking: makeSelectUriIsBlockingOrUnBlocking(props.uri)(state),
-    creatorId: makeSelectClaimIdForUri(props.creatorUri)(state),
+    creatorId: selectClaimIdForUri(state, props.creatorUri),
   };
 };
 
diff --git a/ui/component/channelContent/index.js b/ui/component/channelContent/index.js
index fc1a349f0..46e9b29eb 100644
--- a/ui/component/channelContent/index.js
+++ b/ui/component/channelContent/index.js
@@ -3,9 +3,9 @@ import { PAGE_SIZE } from 'constants/claim';
 import {
   makeSelectClaimsInChannelForPage,
   makeSelectFetchingChannelClaims,
-  makeSelectClaimIsMine,
+  selectClaimIsMine,
   makeSelectTotalPagesInChannelSearch,
-  makeSelectClaimForUri,
+  selectClaimForUri,
 } from 'redux/selectors/claims';
 import { doResolveUris } from 'redux/actions/claims';
 import * as SETTINGS from 'constants/settings';
@@ -20,13 +20,15 @@ const select = (state, props) => {
   const { search } = props.location;
   const urlParams = new URLSearchParams(search);
   const page = urlParams.get('page') || 0;
+  const claim = props.uri && selectClaimForUri(state, props.uri);
+
   return {
     pageOfClaimsInChannel: makeSelectClaimsInChannelForPage(props.uri, page)(state),
     fetching: makeSelectFetchingChannelClaims(props.uri)(state),
     totalPages: makeSelectTotalPagesInChannelSearch(props.uri, PAGE_SIZE)(state),
-    channelIsMine: makeSelectClaimIsMine(props.uri)(state),
+    channelIsMine: selectClaimIsMine(state, claim),
     channelIsBlocked: makeSelectChannelIsMuted(props.uri)(state),
-    claim: props.uri && makeSelectClaimForUri(props.uri)(state),
+    claim,
     isAuthenticated: selectUserVerifiedEmail(state),
     showMature: selectShowMatureContent(state),
     tileLayout: makeSelectClientSetting(SETTINGS.TILE_LAYOUT)(state),
diff --git a/ui/component/channelStakedIndicator/index.js b/ui/component/channelStakedIndicator/index.js
index d217012a4..3a1a41107 100644
--- a/ui/component/channelStakedIndicator/index.js
+++ b/ui/component/channelStakedIndicator/index.js
@@ -1,15 +1,15 @@
 import { connect } from 'react-redux';
 import {
   makeSelectClaimForUri,
-  makeSelectStakedLevelForChannelUri,
-  makeSelectTotalStakedAmountForChannelUri,
+  selectTotalStakedAmountForChannelUri,
+  selectStakedLevelForChannelUri,
 } from 'redux/selectors/claims';
 import ChannelStakedIndicator from './view';
 
 const select = (state, props) => ({
   channelClaim: makeSelectClaimForUri(props.uri)(state),
-  amount: makeSelectTotalStakedAmountForChannelUri(props.uri)(state),
-  level: makeSelectStakedLevelForChannelUri(props.uri)(state),
+  amount: selectTotalStakedAmountForChannelUri(state, props.uri),
+  level: selectStakedLevelForChannelUri(state, props.uri),
 });
 
 export default connect(select)(ChannelStakedIndicator);
diff --git a/ui/component/claimMenuList/index.js b/ui/component/claimMenuList/index.js
index 2f00b8766..847270381 100644
--- a/ui/component/claimMenuList/index.js
+++ b/ui/component/claimMenuList/index.js
@@ -1,5 +1,5 @@
 import { connect } from 'react-redux';
-import { makeSelectClaimForUri, makeSelectClaimIsMine } from 'redux/selectors/claims';
+import { selectClaimForUri, selectClaimIsMine } from 'redux/selectors/claims';
 import { doCollectionEdit, doFetchItemsInCollection } from 'redux/actions/collections';
 import { doPrepareEdit } from 'redux/actions/publish';
 import {
@@ -34,7 +34,7 @@ import ClaimPreview from './view';
 import fs from 'fs';
 
 const select = (state, props) => {
-  const claim = makeSelectClaimForUri(props.uri, false)(state);
+  const claim = selectClaimForUri(state, props.uri, false); // @KP test no repost!
   const collectionId = props.collectionId;
   const repostedClaim = claim && claim.reposted_claim;
   const contentClaim = repostedClaim || claim;
@@ -51,7 +51,7 @@ const select = (state, props) => {
     contentClaim,
     contentSigningChannel,
     contentChannelUri,
-    claimIsMine: makeSelectClaimIsMine(props.uri)(state),
+    claimIsMine: selectClaimIsMine(state, claim),
     hasClaimInWatchLater: makeSelectCollectionForIdHasClaimUrl(
       COLLECTIONS_CONSTS.WATCH_LATER_ID,
       contentPermanentUri
@@ -92,7 +92,7 @@ const perform = (dispatch) => ({
   doChannelUnmute: (channelUri) => dispatch(doChannelUnmute(channelUri)),
   doCommentModBlock: (channelUri) => dispatch(doCommentModBlock(channelUri)),
   doCommentModUnBlock: (channelUri) => dispatch(doCommentModUnBlock(channelUri)),
-  doCommentModBlockAsAdmin: (commenterUri, blockerId) => dispatch(doCommentModBlockAsAdmin(commenterUri, blockerId)),
+  doCommentModBlockAsAdmin: (a, b, c) => dispatch(doCommentModBlockAsAdmin(a, b, c)),
   doCommentModUnBlockAsAdmin: (commenterUri, blockerId) =>
     dispatch(doCommentModUnBlockAsAdmin(commenterUri, blockerId)),
   doChannelSubscribe: (subscription) => dispatch(doChannelSubscribe(subscription)),
diff --git a/ui/component/claimPreview/index.js b/ui/component/claimPreview/index.js
index 25ab46a8b..65efab5d6 100644
--- a/ui/component/claimPreview/index.js
+++ b/ui/component/claimPreview/index.js
@@ -2,7 +2,7 @@ import { connect } from 'react-redux';
 import {
   selectClaimForUri,
   makeSelectIsUriResolving,
-  makeSelectClaimIsMine,
+  selectClaimIsMine,
   makeSelectClaimIsPending,
   makeSelectClaimIsNsfw,
   makeSelectReflectingClaimForUri,
@@ -20,12 +20,10 @@ import {
 import { doResolveUri } from 'redux/actions/claims';
 import { doCollectionEdit } from 'redux/actions/collections';
 import { doFileGet } from 'redux/actions/file';
-import { selectMutedChannels, makeSelectChannelIsMuted } from 'redux/selectors/blocked';
-import { selectBlackListedOutpoints, selectFilteredOutpoints } from 'lbryinc';
+import { selectBanStateForUri } from 'lbryinc';
 import { selectShowMatureContent } from 'redux/selectors/settings';
 import { makeSelectHasVisitedUri } from 'redux/selectors/content';
 import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions';
-import { selectModerationBlockList } from 'redux/selectors/comments';
 import ClaimPreview from './view';
 import formatMediaDuration from 'util/formatMediaDuration';
 
@@ -42,16 +40,12 @@ const select = (state, props) => {
     pending: props.uri && makeSelectClaimIsPending(props.uri)(state),
     reflectingProgress: props.uri && makeSelectReflectingClaimForUri(props.uri)(state),
     obscureNsfw: selectShowMatureContent(state) === false,
-    claimIsMine: props.uri && makeSelectClaimIsMine(props.uri)(state),
+    claimIsMine: props.uri && selectClaimIsMine(state, claim),
     isResolvingUri: props.uri && makeSelectIsUriResolving(props.uri)(state),
     isResolvingRepost: props.uri && makeSelectIsUriResolving(props.repostUrl)(state),
     nsfw: props.uri && makeSelectClaimIsNsfw(props.uri)(state),
-    blackListedOutpoints: selectBlackListedOutpoints(state),
-    filteredOutpoints: selectFilteredOutpoints(state),
-    mutedUris: selectMutedChannels(state),
-    blockedUris: selectModerationBlockList(state),
+    banState: selectBanStateForUri(state, props.uri),
     hasVisitedUri: props.uri && makeSelectHasVisitedUri(props.uri)(state),
-    channelIsBlocked: props.uri && makeSelectChannelIsMuted(props.uri)(state),
     isSubscribed: props.uri && makeSelectIsSubscribed(props.uri, true)(state),
     streamingUrl: props.uri && makeSelectStreamingUrlForUri(props.uri)(state),
     wasPurchased: props.uri && makeSelectClaimWasPurchased(props.uri)(state),
diff --git a/ui/component/claimPreview/view.jsx b/ui/component/claimPreview/view.jsx
index 8903c28c2..b85ce32aa 100644
--- a/ui/component/claimPreview/view.jsx
+++ b/ui/component/claimPreview/view.jsx
@@ -4,7 +4,7 @@ import React, { useEffect, forwardRef } from 'react';
 import { NavLink, withRouter } from 'react-router-dom';
 import { isEmpty } from 'util/object';
 import classnames from 'classnames';
-import { isURIEqual, isURIValid } from 'util/lbryURI';
+import { isURIValid } from 'util/lbryURI';
 import * as COLLECTIONS_CONSTS from 'constants/collections';
 import { formatLbryUrlForWeb } from 'util/url';
 import { formatClaimPreviewTitle } from 'util/formatAriaLabel';
@@ -46,17 +46,8 @@ type Props = {
   nsfw: boolean,
   placeholder: string,
   type: string,
+  banState: { blacklisted?: boolean, filtered?: boolean, muted?: boolean, blocked?: boolean },
   hasVisitedUri: boolean,
-  blackListedOutpoints: Array<{
-    txid: string,
-    nout: number,
-  }>,
-  filteredOutpoints: Array<{
-    txid: string,
-    nout: number,
-  }>,
-  mutedUris: Array<string>,
-  blockedUris: Array<string>,
   channelIsBlocked: boolean,
   actions: boolean | Node | string | number,
   properties: boolean | Node | string | number | ((Claim) => Node),
@@ -131,10 +122,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
     properties,
     onClick,
     actions,
-    mutedUris,
-    blockedUris,
-    blackListedOutpoints,
-    filteredOutpoints,
+    banState,
     includeSupportAction,
     renderActions,
     hideMenu = false,
@@ -236,28 +224,13 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
     ((abandoned && !showUnresolvedClaim) || (!claimIsMine && obscureNsfw && nsfw));
 
   // This will be replaced once blocking is done at the wallet server level
-  if (claim && !claimIsMine && !shouldHide && blackListedOutpoints) {
-    shouldHide = blackListedOutpoints.some(
-      (outpoint) =>
-        (signingChannel && outpoint.txid === signingChannel.txid && outpoint.nout === signingChannel.nout) ||
-        (outpoint.txid === claim.txid && outpoint.nout === claim.nout)
-    );
-  }
-  // We're checking to see if the stream outpoint
-  // or signing channel outpoint is in the filter list
-  if (claim && !claimIsMine && !shouldHide && filteredOutpoints) {
-    shouldHide = filteredOutpoints.some(
-      (outpoint) =>
-        (signingChannel && outpoint.txid === signingChannel.txid && outpoint.nout === signingChannel.nout) ||
-        (outpoint.txid === claim.txid && outpoint.nout === claim.nout)
-    );
+  if (claim && !claimIsMine && (banState.blacklisted || banState.filtered)) {
+    shouldHide = true;
   }
+
   // block stream claims
-  if (claim && !shouldHide && !showUserBlocked && mutedUris.length && signingChannel) {
-    shouldHide = mutedUris.some((blockedUri) => isURIEqual(blockedUri, signingChannel.permanent_url));
-  }
-  if (claim && !shouldHide && !showUserBlocked && blockedUris.length && signingChannel) {
-    shouldHide = blockedUris.some((blockedUri) => isURIEqual(blockedUri, signingChannel.permanent_url));
+  if (!shouldHide && !showUserBlocked && (banState.muted || banState.blocked)) {
+    shouldHide = true;
   }
 
   if (!shouldHide && customShouldHide && claim) {
diff --git a/ui/component/claimPreviewTile/index.js b/ui/component/claimPreviewTile/index.js
index eaf64a865..7d1e558d4 100644
--- a/ui/component/claimPreviewTile/index.js
+++ b/ui/component/claimPreviewTile/index.js
@@ -11,7 +11,7 @@ import {
 import { doFileGet } from 'redux/actions/file';
 import { doResolveUri } from 'redux/actions/claims';
 import { selectMutedChannels } from 'redux/selectors/blocked';
-import { makeSelectViewCountForUri, selectBlackListedOutpoints, selectFilteredOutpoints } from 'lbryinc';
+import { selectViewCountForUri, selectBanStateForUri } from 'lbryinc';
 import { selectShowMatureContent } from 'redux/selectors/settings';
 import ClaimPreviewTile from './view';
 import formatMediaDuration from 'util/formatMediaDuration';
@@ -29,12 +29,11 @@ const select = (state, props) => {
     isResolvingUri: props.uri && makeSelectIsUriResolving(props.uri)(state),
     thumbnail: props.uri && makeSelectThumbnailForUri(props.uri)(state),
     title: props.uri && makeSelectTitleForUri(props.uri)(state),
-    blackListedOutpoints: selectBlackListedOutpoints(state),
-    filteredOutpoints: selectFilteredOutpoints(state),
+    banState: selectBanStateForUri(state, props.uri),
     blockedChannelUris: selectMutedChannels(state),
     showMature: selectShowMatureContent(state),
     isMature: makeSelectClaimIsNsfw(props.uri)(state),
-    viewCount: makeSelectViewCountForUri(props.uri)(state),
+    viewCount: selectViewCountForUri(state, props.uri),
   };
 };
 
diff --git a/ui/component/claimPreviewTile/view.jsx b/ui/component/claimPreviewTile/view.jsx
index 1c921f64e..f68fc1c22 100644
--- a/ui/component/claimPreviewTile/view.jsx
+++ b/ui/component/claimPreviewTile/view.jsx
@@ -12,7 +12,7 @@ import SubscribeButton from 'component/subscribeButton';
 import useGetThumbnail from 'effects/use-get-thumbnail';
 import { formatLbryUrlForWeb, generateListSearchUrlParams } from 'util/url';
 import { formatClaimPreviewTitle } from 'util/formatAriaLabel';
-import { parseURI, isURIEqual } from 'util/lbryURI';
+import { parseURI } from 'util/lbryURI';
 import PreviewOverlayProperties from 'component/previewOverlayProperties';
 import FileDownloadLink from 'component/fileDownloadLink';
 import FileWatchLaterLink from 'component/fileWatchLaterLink';
@@ -33,15 +33,7 @@ type Props = {
   thumbnail: string,
   title: string,
   placeholder: boolean,
-  blackListedOutpoints: Array<{
-    txid: string,
-    nout: number,
-  }>,
-  filteredOutpoints: Array<{
-    txid: string,
-    nout: number,
-  }>,
-  blockedChannelUris: Array<string>,
+  banState: { blacklisted?: boolean, filtered?: boolean, muted?: boolean, blocked?: boolean },
   getFile: (string) => void,
   streamingUrl: string,
   isMature: boolean,
@@ -64,11 +56,9 @@ function ClaimPreviewTile(props: Props) {
     resolveUri,
     claim,
     placeholder,
-    blackListedOutpoints,
-    filteredOutpoints,
+    banState,
     getFile,
     streamingUrl,
-    blockedChannelUris,
     isMature,
     showMature,
     showHiddenByUser,
@@ -139,34 +129,9 @@ function ClaimPreviewTile(props: Props) {
     // Unfortunately needed until this is resolved
     // https://github.com/lbryio/lbry-sdk/issues/2785
     shouldHide = true;
-  }
-
-  // This will be replaced once blocking is done at the wallet server level
-  if (claim && !shouldHide && blackListedOutpoints) {
-    shouldHide = blackListedOutpoints.some(
-      (outpoint) =>
-        (signingChannel && outpoint.txid === signingChannel.txid && outpoint.nout === signingChannel.nout) ||
-        (outpoint.txid === claim.txid && outpoint.nout === claim.nout)
-    );
-  }
-  // We're checking to see if the stream outpoint
-  // or signing channel outpoint is in the filter list
-  if (claim && !shouldHide && filteredOutpoints) {
-    shouldHide = filteredOutpoints.some(
-      (outpoint) =>
-        (signingChannel && outpoint.txid === signingChannel.txid && outpoint.nout === signingChannel.nout) ||
-        (outpoint.txid === claim.txid && outpoint.nout === claim.nout)
-    );
-  }
-
-  // block stream claims
-  if (claim && !shouldHide && !showHiddenByUser && blockedChannelUris.length && signingChannel) {
-    shouldHide = blockedChannelUris.some((blockedUri) => isURIEqual(blockedUri, signingChannel.permanent_url));
-  }
-  // block channel claims if we can't control for them in claim search
-  // e.g. fetchRecommendedSubscriptions
-  if (claim && isChannel && !shouldHide && !showHiddenByUser && blockedChannelUris.length && signingChannel) {
-    shouldHide = blockedChannelUris.some((blockedUri) => isURIEqual(blockedUri, signingChannel.permanent_url));
+  } else {
+    shouldHide =
+      banState.blacklisted || banState.filtered || (!showHiddenByUser && (banState.muted || banState.blocked));
   }
 
   if (shouldHide) {
@@ -280,34 +245,4 @@ function ClaimPreviewTile(props: Props) {
   );
 }
 
-export default React.memo<Props>(withRouter(ClaimPreviewTile), areEqual);
-
-const BLOCKLIST_KEYS = ['blackListedOutpoints', 'filteredOutpoints', 'blockedChannelUris'];
-const HANDLED_KEYS = [...BLOCKLIST_KEYS, 'date'];
-
-function areEqual(prev: Props, next: Props) {
-  for (let i = 0; i < BLOCKLIST_KEYS.length; ++i) {
-    const key = BLOCKLIST_KEYS[i];
-    const a = prev[key];
-    const b = next[key];
-
-    if (((!a || !b) && a !== b) || (a && b && a.length !== b.length)) {
-      // The arrays are huge, so just compare the length instead of each entry.
-      return false;
-    }
-  }
-
-  if (Number(prev.date) !== Number(next.date)) {
-    return false;
-  }
-
-  const propKeys = Object.keys(next);
-  for (let i = 0; i < propKeys.length; ++i) {
-    const pk = propKeys[i];
-    if (!HANDLED_KEYS.includes(pk) && prev[pk] !== next[pk]) {
-      return false;
-    }
-  }
-
-  return true;
-}
+export default withRouter(ClaimPreviewTile);
diff --git a/ui/component/claimProperties/index.js b/ui/component/claimProperties/index.js
index 574ceb0e1..3b5f3edf6 100644
--- a/ui/component/claimProperties/index.js
+++ b/ui/component/claimProperties/index.js
@@ -1,12 +1,16 @@
 import { connect } from 'react-redux';
-import { makeSelectClaimIsMine, makeSelectClaimForUri } from 'redux/selectors/claims';
+import { selectClaimIsMine, selectClaimForUri } from 'redux/selectors/claims';
 import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions';
 import ClaimProperties from './view';
 
-const select = (state, props) => ({
-  claim: makeSelectClaimForUri(props.uri)(state),
-  isSubscribed: makeSelectIsSubscribed(props.uri)(state),
-  claimIsMine: makeSelectClaimIsMine(props.uri)(state),
-});
+const select = (state, props) => {
+  const claim = selectClaimForUri(state, props.uri);
+
+  return {
+    claim,
+    isSubscribed: makeSelectIsSubscribed(props.uri)(state),
+    claimIsMine: selectClaimIsMine(state, claim),
+  };
+};
 
 export default connect(select, null)(ClaimProperties);
diff --git a/ui/component/collectionContentSidebar/index.js b/ui/component/collectionContentSidebar/index.js
index e07304052..e65f79f84 100644
--- a/ui/component/collectionContentSidebar/index.js
+++ b/ui/component/collectionContentSidebar/index.js
@@ -1,6 +1,6 @@
 import { connect } from 'react-redux';
 import CollectionContent from './view';
-import { makeSelectClaimForUri, makeSelectClaimIsMine } from 'redux/selectors/claims';
+import { selectClaimForUri, selectClaimIsMine } from 'redux/selectors/claims';
 import {
   makeSelectUrlsForCollectionId,
   makeSelectNameForCollectionId,
@@ -12,7 +12,7 @@ import { doToggleLoopList, doToggleShuffleList } from 'redux/actions/content';
 const select = (state, props) => {
   const playingUri = selectPlayingUri(state);
   const playingUrl = playingUri && playingUri.uri;
-  const claim = makeSelectClaimForUri(playingUrl)(state);
+  const claim = selectClaimForUri(state, playingUrl);
   const url = claim && claim.permanent_url;
   const loopList = selectListLoop(state);
   const loop = loopList && loopList.collectionId === props.id && loopList.loop;
@@ -24,7 +24,7 @@ const select = (state, props) => {
     collection: makeSelectCollectionForId(props.id)(state),
     collectionUrls: makeSelectUrlsForCollectionId(props.id)(state),
     collectionName: makeSelectNameForCollectionId(props.id)(state),
-    isMine: makeSelectClaimIsMine(url)(state),
+    isMine: selectClaimIsMine(state, claim),
     loop,
     shuffle,
   };
diff --git a/ui/component/collectionPreviewOverlay/index.js b/ui/component/collectionPreviewOverlay/index.js
index 8c04f7020..caee0c5c9 100644
--- a/ui/component/collectionPreviewOverlay/index.js
+++ b/ui/component/collectionPreviewOverlay/index.js
@@ -1,5 +1,5 @@
 import { connect } from 'react-redux';
-import { makeSelectIsUriResolving, makeSelectClaimIdForUri, makeSelectClaimForClaimId } from 'redux/selectors/claims';
+import { makeSelectIsUriResolving, selectClaimIdForUri, makeSelectClaimForClaimId } from 'redux/selectors/claims';
 import {
   makeSelectUrlsForCollectionId,
   makeSelectNameForCollectionId,
@@ -10,7 +10,7 @@ import { doFetchItemsInCollection } from 'redux/actions/collections';
 import CollectionPreviewOverlay from './view';
 
 const select = (state, props) => {
-  const collectionId = props.collectionId || (props.uri && makeSelectClaimIdForUri(props.uri)(state));
+  const collectionId = props.collectionId || (props.uri && selectClaimIdForUri(state, props.uri));
   const claim = props.collectionId && makeSelectClaimForClaimId(props.collectionId)(state);
   const collectionUri = props.uri || (claim && (claim.canonical_url || claim.permanent_url)) || null;
 
diff --git a/ui/component/collectionPreviewTile/index.js b/ui/component/collectionPreviewTile/index.js
index c3a5cc65b..706cd974d 100644
--- a/ui/component/collectionPreviewTile/index.js
+++ b/ui/component/collectionPreviewTile/index.js
@@ -5,7 +5,7 @@ import {
   makeSelectTitleForUri,
   makeSelectChannelForClaimUri,
   makeSelectClaimIsNsfw,
-  makeSelectClaimIdForUri,
+  selectClaimIdForUri,
   makeSelectClaimForClaimId,
 } from 'redux/selectors/claims';
 import {
@@ -24,7 +24,7 @@ import { selectShowMatureContent } from 'redux/selectors/settings';
 import CollectionPreviewTile from './view';
 
 const select = (state, props) => {
-  const collectionId = props.collectionId || (props.uri && makeSelectClaimIdForUri(props.uri)(state));
+  const collectionId = props.collectionId || (props.uri && selectClaimIdForUri(state, props.uri));
   const claim = props.collectionId && makeSelectClaimForClaimId(props.collectionId)(state);
   const collectionUri = props.uri || (claim && (claim.canonical_url || claim.permanent_url)) || null;
 
diff --git a/ui/component/comment/index.js b/ui/component/comment/index.js
index ffe06dd37..b5c336522 100644
--- a/ui/component/comment/index.js
+++ b/ui/component/comment/index.js
@@ -1,6 +1,6 @@
 import { connect } from 'react-redux';
 import {
-  makeSelectStakedLevelForChannelUri,
+  selectTotalStakedAmountForChannelUri,
   makeSelectClaimForUri,
   makeSelectThumbnailForUri,
   selectMyChannelClaims,
@@ -33,7 +33,7 @@ const select = (state, props) => {
     activeChannelClaim,
     myChannels: selectMyChannelClaims(state),
     playingUri: selectPlayingUri(state),
-    stakedLevel: makeSelectStakedLevelForChannelUri(props.authorUri)(state),
+    stakedLevel: selectTotalStakedAmountForChannelUri(state, props.authorUri),
     linkedCommentAncestors: selectLinkedCommentAncestors(state),
     totalReplyPages: makeSelectTotalReplyPagesForParentId(props.commentId)(state),
   };
diff --git a/ui/component/commentCreate/index.js b/ui/component/commentCreate/index.js
index 61d209e5d..ff760c3e3 100644
--- a/ui/component/commentCreate/index.js
+++ b/ui/component/commentCreate/index.js
@@ -1,8 +1,8 @@
 import { connect } from 'react-redux';
 import {
-  makeSelectClaimForUri,
-  makeSelectClaimIsMine,
-  selectMyChannelClaims,
+  selectClaimForUri,
+  selectClaimIsMine,
+  selectHasChannels,
   selectFetchingMyChannels,
   makeSelectTagInClaimOrChannelForUri,
 } from 'redux/selectors/claims';
@@ -14,15 +14,18 @@ import { CommentCreate } from './view';
 import { doToast } from 'redux/actions/notifications';
 import { DISABLE_SUPPORT_TAG } from 'constants/tags';
 
-const select = (state, props) => ({
-  claim: makeSelectClaimForUri(props.uri)(state),
-  channels: selectMyChannelClaims(state),
-  isFetchingChannels: selectFetchingMyChannels(state),
-  activeChannelClaim: selectActiveChannelClaim(state),
-  claimIsMine: makeSelectClaimIsMine(props.uri)(state),
-  settingsByChannelId: selectSettingsByChannelId(state),
-  supportDisabled: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_SUPPORT_TAG)(state),
-});
+const select = (state, props) => {
+  const claim = selectClaimForUri(state, props.uri);
+  return {
+    activeChannelClaim: selectActiveChannelClaim(state),
+    hasChannels: selectHasChannels(state),
+    claim,
+    claimIsMine: selectClaimIsMine(state, claim),
+    isFetchingChannels: selectFetchingMyChannels(state),
+    settingsByChannelId: selectSettingsByChannelId(state),
+    supportDisabled: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_SUPPORT_TAG)(state),
+  };
+};
 
 const perform = (dispatch, ownProps) => ({
   createComment: (comment, claimId, parentId, txid, payment_intent_id, environment) =>
diff --git a/ui/component/commentMenuList/index.js b/ui/component/commentMenuList/index.js
index 62ddf4c8b..ce91b592d 100644
--- a/ui/component/commentMenuList/index.js
+++ b/ui/component/commentMenuList/index.js
@@ -4,24 +4,22 @@ import { doCommentPin, doCommentModAddDelegate } from 'redux/actions/comments';
 import { doOpenModal } from 'redux/actions/app';
 import { doSetPlayingUri } from 'redux/actions/content';
 import { doToast } from 'redux/actions/notifications';
-import {
-  makeSelectChannelPermUrlForClaimUri,
-  makeSelectClaimIsMine,
-  makeSelectClaimForUri,
-} from 'redux/selectors/claims';
+import { selectClaimIsMine, selectClaimForUri } from 'redux/selectors/claims';
 import { selectActiveChannelClaim } from 'redux/selectors/app';
 import { selectModerationDelegatorsById } from 'redux/selectors/comments';
 import { selectPlayingUri } from 'redux/selectors/content';
 import CommentMenuList from './view';
 
-const select = (state, props) => ({
-  claim: makeSelectClaimForUri(props.uri)(state),
-  claimIsMine: makeSelectClaimIsMine(props.uri)(state),
-  contentChannelPermanentUrl: makeSelectChannelPermUrlForClaimUri(props.uri)(state),
-  activeChannelClaim: selectActiveChannelClaim(state),
-  playingUri: selectPlayingUri(state),
-  moderationDelegatorsById: selectModerationDelegatorsById(state),
-});
+const select = (state, props) => {
+  const claim = selectClaimForUri(state, props.uri);
+  return {
+    claim,
+    claimIsMine: selectClaimIsMine(state, claim),
+    activeChannelClaim: selectActiveChannelClaim(state),
+    playingUri: selectPlayingUri(state),
+    moderationDelegatorsById: selectModerationDelegatorsById(state),
+  };
+};
 
 const perform = (dispatch) => ({
   openModal: (modal, props) => dispatch(doOpenModal(modal, props)),
diff --git a/ui/component/commentReactions/index.js b/ui/component/commentReactions/index.js
index b2de27008..86dfcdd4f 100644
--- a/ui/component/commentReactions/index.js
+++ b/ui/component/commentReactions/index.js
@@ -1,6 +1,6 @@
 import { connect } from 'react-redux';
 import Comment from './view';
-import { makeSelectClaimIsMine, makeSelectClaimForUri } from 'redux/selectors/claims';
+import { selectClaimIsMine, selectClaimForUri } from 'redux/selectors/claims';
 import { doResolveUri } from 'redux/actions/claims';
 import { doToast } from 'redux/actions/notifications';
 import { selectMyReactsForComment, selectOthersReactsForComment } from 'redux/selectors/comments';
@@ -11,10 +11,11 @@ const select = (state, props) => {
   const activeChannelClaim = selectActiveChannelClaim(state);
   const activeChannelId = activeChannelClaim && activeChannelClaim.claim_id;
   const reactionKey = activeChannelId ? `${props.commentId}:${activeChannelId}` : props.commentId;
+  const claim = selectClaimForUri(state, props.uri);
 
   return {
-    claim: makeSelectClaimForUri(props.uri)(state),
-    claimIsMine: makeSelectClaimIsMine(props.uri)(state),
+    claim,
+    claimIsMine: selectClaimIsMine(state, claim),
     myReacts: selectMyReactsForComment(state, reactionKey),
     othersReacts: selectOthersReactsForComment(state, reactionKey),
     activeChannelId,
diff --git a/ui/component/commentsList/index.js b/ui/component/commentsList/index.js
index 4b09b9b4f..53712cf93 100644
--- a/ui/component/commentsList/index.js
+++ b/ui/component/commentsList/index.js
@@ -1,10 +1,11 @@
 import { connect } from 'react-redux';
 import { doResolveUris } from 'redux/actions/claims';
 import {
+  selectClaimForUri,
   makeSelectClaimForUri,
-  makeSelectClaimIsMine,
+  selectClaimIsMine,
   selectFetchingMyChannels,
-  selectMyChannelClaims,
+  selectMyClaimIdsRaw,
 } from 'redux/selectors/claims';
 import {
   selectTopLevelCommentsForUri,
@@ -15,7 +16,7 @@ import {
   makeSelectTotalCommentsCountForUri,
   selectOthersReacts,
   selectMyReacts,
-  makeSelectCommentIdsForUri,
+  selectCommentIdsForUri,
   selectSettingsByChannelId,
   selectPinnedCommentsForUri,
 } from 'redux/selectors/comments';
@@ -24,6 +25,7 @@ import { selectActiveChannelClaim } from 'redux/selectors/app';
 import CommentsList from './view';
 
 const select = (state, props) => {
+  const claim = selectClaimForUri(state, props.uri);
   const activeChannelClaim = selectActiveChannelClaim(state);
   const topLevelComments = selectTopLevelCommentsForUri(state, props.uri);
 
@@ -35,13 +37,13 @@ const select = (state, props) => {
   return {
     topLevelComments,
     resolvedComments,
-    myChannels: selectMyChannelClaims(state),
-    allCommentIds: makeSelectCommentIdsForUri(props.uri)(state),
+    myChannelIds: selectMyClaimIdsRaw(state),
+    allCommentIds: selectCommentIdsForUri(state, props.uri),
     pinnedComments: selectPinnedCommentsForUri(state, props.uri),
     topLevelTotalPages: makeSelectTopLevelTotalPagesForUri(props.uri)(state),
     totalComments: makeSelectTotalCommentsCountForUri(props.uri)(state),
-    claim: makeSelectClaimForUri(props.uri)(state),
-    claimIsMine: makeSelectClaimIsMine(props.uri)(state),
+    claim,
+    claimIsMine: selectClaimIsMine(state, claim),
     isFetchingComments: selectIsFetchingComments(state),
     isFetchingCommentsById: selectIsFetchingCommentsById(state),
     isFetchingReacts: selectIsFetchingReacts(state),
diff --git a/ui/component/fileActions/index.js b/ui/component/fileActions/index.js
index 3fe529ce9..78d76d263 100644
--- a/ui/component/fileActions/index.js
+++ b/ui/component/fileActions/index.js
@@ -1,8 +1,8 @@
 import { connect } from 'react-redux';
 import {
-  makeSelectClaimIsMine,
-  makeSelectClaimForUri,
-  selectMyChannelClaims,
+  selectClaimIsMine,
+  selectClaimForUri,
+  selectHasChannels,
   makeSelectTagInClaimOrChannelForUri,
 } from 'redux/selectors/claims';
 import { makeSelectStreamingUrlForUri, makeSelectFileInfoForUri } from 'redux/selectors/file_info';
@@ -16,16 +16,20 @@ import fs from 'fs';
 import FileActions from './view';
 import { makeSelectFileRenderModeForUri } from 'redux/selectors/content';
 
-const select = (state, props) => ({
-  claim: makeSelectClaimForUri(props.uri)(state),
-  claimIsMine: makeSelectClaimIsMine(props.uri)(state),
-  fileInfo: makeSelectFileInfoForUri(props.uri)(state),
-  renderMode: makeSelectFileRenderModeForUri(props.uri)(state),
-  costInfo: makeSelectCostInfoForUri(props.uri)(state),
-  myChannels: selectMyChannelClaims(state),
-  reactionsDisabled: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_COMMENTS_TAG)(state),
-  streamingUrl: makeSelectStreamingUrlForUri(props.uri)(state),
-});
+const select = (state, props) => {
+  const claim = selectClaimForUri(state, props.uri);
+
+  return {
+    claim,
+    claimIsMine: selectClaimIsMine(state, claim),
+    fileInfo: makeSelectFileInfoForUri(props.uri)(state),
+    renderMode: makeSelectFileRenderModeForUri(props.uri)(state),
+    costInfo: makeSelectCostInfoForUri(props.uri)(state),
+    hasChannels: selectHasChannels(state),
+    reactionsDisabled: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_COMMENTS_TAG)(state),
+    streamingUrl: makeSelectStreamingUrlForUri(props.uri)(state),
+  };
+};
 
 const perform = (dispatch) => ({
   openModal: (modal, props) => dispatch(doOpenModal(modal, props)),
diff --git a/ui/component/fileDescription/index.js b/ui/component/fileDescription/index.js
index 5004b7220..d8a119c37 100644
--- a/ui/component/fileDescription/index.js
+++ b/ui/component/fileDescription/index.js
@@ -1,23 +1,27 @@
 import { connect } from 'react-redux';
 import {
-  makeSelectClaimForUri,
+  selectClaimForUri,
   makeSelectMetadataForUri,
+  selectClaimIsMine,
   makeSelectTagsForUri,
-  makeSelectClaimIsMine,
 } from 'redux/selectors/claims';
 import { makeSelectPendingAmountByUri } from 'redux/selectors/wallet';
 import { doOpenModal } from 'redux/actions/app';
 import { selectUser } from 'redux/selectors/user';
 import FileDescription from './view';
 
-const select = (state, props) => ({
-  claim: makeSelectClaimForUri(props.uri)(state),
-  claimIsMine: makeSelectClaimIsMine(props.uri)(state),
-  metadata: makeSelectMetadataForUri(props.uri)(state),
-  user: selectUser(state),
-  tags: makeSelectTagsForUri(props.uri)(state),
-  pendingAmount: makeSelectPendingAmountByUri(props.uri)(state),
-});
+const select = (state, props) => {
+  const claim = selectClaimForUri(state, props.uri);
+
+  return {
+    claim,
+    claimIsMine: selectClaimIsMine(state, claim),
+    metadata: makeSelectMetadataForUri(props.uri)(state),
+    user: selectUser(state),
+    pendingAmount: makeSelectPendingAmountByUri(props.uri)(state),
+    tags: makeSelectTagsForUri(props.uri)(state),
+  };
+};
 
 export default connect(select, {
   doOpenModal,
diff --git a/ui/component/fileDownloadLink/index.js b/ui/component/fileDownloadLink/index.js
index 41e32d044..bf4ad34d3 100644
--- a/ui/component/fileDownloadLink/index.js
+++ b/ui/component/fileDownloadLink/index.js
@@ -1,5 +1,5 @@
 import { connect } from 'react-redux';
-import { makeSelectClaimIsMine, makeSelectClaimForUri, makeSelectClaimWasPurchased } from 'redux/selectors/claims';
+import { selectClaimIsMine, selectClaimForUri, makeSelectClaimWasPurchased } from 'redux/selectors/claims';
 import {
   makeSelectFileInfoForUri,
   makeSelectDownloadingForUri,
@@ -11,16 +11,20 @@ import { doOpenModal, doAnalyticsView } from 'redux/actions/app';
 import { doSetPlayingUri, doPlayUri } from 'redux/actions/content';
 import FileDownloadLink from './view';
 
-const select = (state, props) => ({
-  fileInfo: makeSelectFileInfoForUri(props.uri)(state),
-  downloading: makeSelectDownloadingForUri(props.uri)(state),
-  loading: makeSelectLoadingForUri(props.uri)(state),
-  claimIsMine: makeSelectClaimIsMine(props.uri)(state),
-  claim: makeSelectClaimForUri(props.uri)(state),
-  costInfo: makeSelectCostInfoForUri(props.uri)(state),
-  claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state),
-  streamingUrl: makeSelectStreamingUrlForUri(props.uri)(state),
-});
+const select = (state, props) => {
+  const claim = selectClaimForUri(state, props.uri);
+
+  return {
+    fileInfo: makeSelectFileInfoForUri(props.uri)(state),
+    downloading: makeSelectDownloadingForUri(props.uri)(state),
+    loading: makeSelectLoadingForUri(props.uri)(state),
+    claimIsMine: selectClaimIsMine(state, claim),
+    claim,
+    costInfo: makeSelectCostInfoForUri(props.uri)(state),
+    claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state),
+    streamingUrl: makeSelectStreamingUrlForUri(props.uri)(state),
+  };
+};
 
 const perform = (dispatch) => ({
   openModal: (modal, props) => dispatch(doOpenModal(modal, props)),
diff --git a/ui/component/filePrice/index.js b/ui/component/filePrice/index.js
index d795184c5..560f38b96 100644
--- a/ui/component/filePrice/index.js
+++ b/ui/component/filePrice/index.js
@@ -1,18 +1,18 @@
 import { connect } from 'react-redux';
-import { makeSelectClaimForUri, makeSelectClaimWasPurchased, makeSelectClaimIsMine } from 'redux/selectors/claims';
+import { selectClaimForUri, makeSelectClaimWasPurchased, selectClaimIsMine } from 'redux/selectors/claims';
 import { makeSelectCostInfoForUri, doFetchCostInfoForUri, makeSelectFetchingCostInfoForUri } from 'lbryinc';
 import FilePrice from './view';
 
-const select = (state, props) => ({
-  costInfo: makeSelectCostInfoForUri(props.uri)(state),
-  fetching: makeSelectFetchingCostInfoForUri(props.uri)(state),
-  claim: makeSelectClaimForUri(props.uri)(state),
-  claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state),
-  claimIsMine: makeSelectClaimIsMine(props.uri)(state),
-});
+const select = (state, props) => {
+  const claim = selectClaimForUri(state, props.uri);
 
-const perform = (dispatch) => ({
-  fetchCostInfo: (uri) => dispatch(doFetchCostInfoForUri(uri)),
-});
+  return {
+    claim,
+    claimIsMine: selectClaimIsMine(state, claim),
+    claimWasPurchased: makeSelectClaimWasPurchased(props.uri)(state),
+    costInfo: makeSelectCostInfoForUri(props.uri)(state),
+    fetching: makeSelectFetchingCostInfoForUri(props.uri)(state),
+  };
+};
 
-export default connect(select, perform)(FilePrice);
+export default connect(select, { doFetchCostInfoForUri })(FilePrice);
diff --git a/ui/component/filePrice/view.jsx b/ui/component/filePrice/view.jsx
index 3f9b1f626..352064d80 100644
--- a/ui/component/filePrice/view.jsx
+++ b/ui/component/filePrice/view.jsx
@@ -8,7 +8,7 @@ import Icon from 'component/common/icon';
 type Props = {
   showFullPrice: boolean,
   costInfo: ?{ includesData: boolean, cost: number },
-  fetchCostInfo: string => void,
+  doFetchCostInfoForUri: (string) => void,
   uri: string,
   fetching: boolean,
   claim: ?{},
@@ -35,10 +35,10 @@ class FilePrice extends React.PureComponent<Props> {
   }
 
   fetchCost = (props: Props) => {
-    const { costInfo, fetchCostInfo, uri, fetching, claim } = props;
+    const { costInfo, doFetchCostInfoForUri, uri, fetching, claim } = props;
 
     if (costInfo === undefined && !fetching && claim) {
-      fetchCostInfo(uri);
+      doFetchCostInfoForUri(uri);
     }
   };
 
diff --git a/ui/component/fileTitleSection/index.js b/ui/component/fileTitleSection/index.js
index 0e9f3a4f9..b012111f5 100644
--- a/ui/component/fileTitleSection/index.js
+++ b/ui/component/fileTitleSection/index.js
@@ -1,5 +1,5 @@
 import { connect } from 'react-redux';
-import { doFetchSubCount, makeSelectSubCountForUri } from 'lbryinc';
+import { doFetchSubCount, selectSubCountForUri } from 'lbryinc';
 import { makeSelectTitleForUri, makeSelectClaimForUri } from 'redux/selectors/claims';
 import { makeSelectInsufficientCreditsForUri } from 'redux/selectors/content';
 import FileTitleSection from './view';
@@ -8,7 +8,7 @@ const select = (state, props) => {
   const claim = makeSelectClaimForUri(props.uri)(state);
   const channelClaimId = claim && claim.signing_channel ? claim.signing_channel.claim_id : undefined;
   const channelUri = claim && claim.signing_channel ? claim.signing_channel.canonical_url : undefined;
-  const subCount = channelUri && makeSelectSubCountForUri(channelUri)(state);
+  const subCount = channelUri && selectSubCountForUri(state, channelUri);
 
   return {
     isInsufficientCredits: makeSelectInsufficientCreditsForUri(props.uri)(state),
diff --git a/ui/component/fileValues/index.js b/ui/component/fileValues/index.js
index 8fe82ba56..a3994d7c3 100644
--- a/ui/component/fileValues/index.js
+++ b/ui/component/fileValues/index.js
@@ -1,9 +1,9 @@
 import { connect } from 'react-redux';
 import {
-  makeSelectClaimForUri,
+  selectClaimForUri,
   makeSelectContentTypeForUri,
   makeSelectMetadataForUri,
-  makeSelectClaimIsMine,
+  selectClaimIsMine,
 } from 'redux/selectors/claims';
 import { makeSelectPendingAmountByUri } from 'redux/selectors/wallet';
 import { makeSelectFileInfoForUri } from 'redux/selectors/file_info';
@@ -12,15 +12,19 @@ import { doOpenModal } from 'redux/actions/app';
 
 import FileValues from './view';
 
-const select = (state, props) => ({
-  claim: makeSelectClaimForUri(props.uri)(state),
-  contentType: makeSelectContentTypeForUri(props.uri)(state),
-  fileInfo: makeSelectFileInfoForUri(props.uri)(state),
-  metadata: makeSelectMetadataForUri(props.uri)(state),
-  user: selectUser(state),
-  pendingAmount: makeSelectPendingAmountByUri(props.uri)(state),
-  claimIsMine: makeSelectClaimIsMine(props.uri)(state),
-});
+const select = (state, props) => {
+  const claim = selectClaimForUri(state, props.uri);
+
+  return {
+    claim,
+    contentType: makeSelectContentTypeForUri(props.uri)(state),
+    fileInfo: makeSelectFileInfoForUri(props.uri)(state),
+    metadata: makeSelectMetadataForUri(props.uri)(state),
+    user: selectUser(state),
+    pendingAmount: makeSelectPendingAmountByUri(props.uri)(state),
+    claimIsMine: selectClaimIsMine(state, claim),
+  };
+};
 
 const perform = (dispatch) => ({
   openModal: (modal, props) => dispatch(doOpenModal(modal, props)),
diff --git a/ui/component/fileViewCount/index.js b/ui/component/fileViewCount/index.js
index e4c5e64d5..d1cec539a 100644
--- a/ui/component/fileViewCount/index.js
+++ b/ui/component/fileViewCount/index.js
@@ -1,12 +1,12 @@
 import { connect } from 'react-redux';
-import { makeSelectClaimForUri } from 'redux/selectors/claims';
-import { doFetchViewCount, makeSelectViewCountForUri } from 'lbryinc';
+import { selectClaimForUri } from 'redux/selectors/claims';
+import { doFetchViewCount, selectViewCountForUri } from 'lbryinc';
 import { doAnalyticsView } from 'redux/actions/app';
 import FileViewCount from './view';
 
 const select = (state, props) => ({
-  claim: makeSelectClaimForUri(props.uri)(state),
-  viewCount: makeSelectViewCountForUri(props.uri)(state),
+  claim: selectClaimForUri(state, props.uri),
+  viewCount: selectViewCountForUri(state, props.uri),
 });
 
 const perform = (dispatch) => ({
diff --git a/ui/component/fileViewCountInline/index.js b/ui/component/fileViewCountInline/index.js
index 0f9f2c1e6..36fdabf98 100644
--- a/ui/component/fileViewCountInline/index.js
+++ b/ui/component/fileViewCountInline/index.js
@@ -1,13 +1,13 @@
 import { connect } from 'react-redux';
-import { makeSelectClaimForUri } from 'redux/selectors/claims';
-import { makeSelectViewCountForUri } from 'lbryinc';
+import { selectClaimForUri } from 'redux/selectors/claims';
+import { selectViewCountForUri } from 'lbryinc';
 import { selectLanguage } from 'redux/selectors/settings';
 import FileViewCountInline from './view';
 
 const select = (state, props) => {
   return {
-    claim: makeSelectClaimForUri(props.uri)(state),
-    viewCount: makeSelectViewCountForUri(props.uri)(state),
+    claim: selectClaimForUri(state, props.uri),
+    viewCount: selectViewCountForUri(state, props.uri),
     lang: selectLanguage(state),
   };
 };
diff --git a/ui/component/previewLink/index.js b/ui/component/previewLink/index.js
index 17493a0ed..9d93d2c63 100644
--- a/ui/component/previewLink/index.js
+++ b/ui/component/previewLink/index.js
@@ -1,9 +1,9 @@
 import { connect } from 'react-redux';
 import {
-  makeSelectClaimIsMine,
+  selectClaimIsMine,
   makeSelectTitleForUri,
   makeSelectThumbnailForUri,
-  makeSelectClaimForUri,
+  selectClaimForUri,
   makeSelectIsUriResolving,
   makeSelectMetadataItemForUri,
 } from 'redux/selectors/claims';
@@ -12,13 +12,15 @@ import { selectBlackListedOutpoints } from 'lbryinc';
 import PreviewLink from './view';
 
 const select = (state, props) => {
+  const claim = selectClaimForUri(state, props.uri);
+
   return {
     uri: props.uri,
-    claim: makeSelectClaimForUri(props.uri)(state),
+    claim,
     title: makeSelectTitleForUri(props.uri)(state),
     thumbnail: makeSelectThumbnailForUri(props.uri)(state),
     description: makeSelectMetadataItemForUri(props.uri, 'description')(state),
-    channelIsMine: makeSelectClaimIsMine(props.uri)(state),
+    channelIsMine: selectClaimIsMine(state, claim),
     isResolvingUri: makeSelectIsUriResolving(props.uri)(state),
     blackListedOutpoints: selectBlackListedOutpoints(state),
   };
diff --git a/ui/component/previewOverlayProperties/index.js b/ui/component/previewOverlayProperties/index.js
index 622fb642b..aa0938a0c 100644
--- a/ui/component/previewOverlayProperties/index.js
+++ b/ui/component/previewOverlayProperties/index.js
@@ -1,19 +1,20 @@
 import { connect } from 'react-redux';
-import { makeSelectClaimIsMine, makeSelectClaimForUri } from 'redux/selectors/claims';
+import { selectClaimIsMine, selectClaimForUri } from 'redux/selectors/claims';
 import { makeSelectFilePartlyDownloaded } from 'redux/selectors/file_info';
 import { makeSelectEditedCollectionForId } from 'redux/selectors/collections';
 import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions';
 import PreviewOverlayProperties from './view';
 
 const select = (state, props) => {
-  const claim = makeSelectClaimForUri(props.uri)(state);
+  const claim = selectClaimForUri(state, props.uri);
   const claimId = claim && claim.claim_id;
+
   return {
     claim,
     editedCollection: makeSelectEditedCollectionForId(claimId)(state),
     downloaded: makeSelectFilePartlyDownloaded(props.uri)(state),
     isSubscribed: makeSelectIsSubscribed(props.uri)(state),
-    claimIsMine: makeSelectClaimIsMine(props.uri)(state),
+    claimIsMine: selectClaimIsMine(state, claim),
   };
 };
 
diff --git a/ui/modal/modalConfirmTransaction/index.js b/ui/modal/modalConfirmTransaction/index.js
index c59a746dd..5a5493099 100644
--- a/ui/modal/modalConfirmTransaction/index.js
+++ b/ui/modal/modalConfirmTransaction/index.js
@@ -1,12 +1,12 @@
 import { connect } from 'react-redux';
 import { doSendDraftTransaction, doSendTip } from 'redux/actions/wallet';
-import { makeSelectClaimForUri } from 'redux/selectors/claims';
+import { selectClaimForUri } from 'redux/selectors/claims';
 import { doHideModal } from 'redux/actions/app';
 import ModalConfirmTransaction from './view';
 import { selectActiveChannelClaim, selectIncognito } from 'redux/selectors/app';
 
 const select = (state, props) => ({
-  claim: makeSelectClaimForUri(props.destination)(state),
+  claim: selectClaimForUri(state, props.destination)(state),
   activeChannelClaim: selectActiveChannelClaim(state),
   incognito: selectIncognito(state),
 });
diff --git a/ui/modal/modalRemoveFile/index.js b/ui/modal/modalRemoveFile/index.js
index bc0fdd321..2a9228f39 100644
--- a/ui/modal/modalRemoveFile/index.js
+++ b/ui/modal/modalRemoveFile/index.js
@@ -2,7 +2,7 @@ import { connect } from 'react-redux';
 import { doDeleteFileAndMaybeGoBack } from 'redux/actions/file';
 import {
   makeSelectTitleForUri,
-  makeSelectClaimForUri,
+  selectClaimForUri,
   makeSelectIsAbandoningClaimForUri,
   makeSelectClaimIsMine,
 } from 'redux/selectors/claims';
@@ -13,7 +13,7 @@ import ModalRemoveFile from './view';
 const select = (state, props) => ({
   claimIsMine: makeSelectClaimIsMine(props.uri)(state),
   title: makeSelectTitleForUri(props.uri)(state),
-  claim: makeSelectClaimForUri(props.uri)(state),
+  claim: selectClaimForUri(state, props.uri),
   isAbandoning: makeSelectIsAbandoningClaimForUri(props.uri)(state),
 });
 
diff --git a/ui/page/channel/index.js b/ui/page/channel/index.js
index 049d0f0ea..4576586d3 100644
--- a/ui/page/channel/index.js
+++ b/ui/page/channel/index.js
@@ -1,15 +1,15 @@
 import { connect } from 'react-redux';
 import {
-  makeSelectClaimIsMine,
+  selectClaimIsMine,
   makeSelectTitleForUri,
   makeSelectThumbnailForUri,
   makeSelectCoverForUri,
   selectCurrentChannelPage,
-  makeSelectClaimForUri,
+  selectClaimForUri,
   makeSelectClaimIsPending,
 } from 'redux/selectors/claims';
 import { selectMyUnpublishedCollections } from 'redux/selectors/collections';
-import { selectBlackListedOutpoints, doFetchSubCount, makeSelectSubCountForUri } from 'lbryinc';
+import { selectBlackListedOutpoints, doFetchSubCount, selectSubCountForUri } from 'lbryinc'; // ban state
 import { selectYoutubeChannels } from 'redux/selectors/user';
 import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions';
 import { selectModerationBlockList } from 'redux/selectors/comments';
@@ -17,22 +17,26 @@ import { selectMutedChannels } from 'redux/selectors/blocked';
 import { doOpenModal } from 'redux/actions/app';
 import ChannelPage from './view';
 
-const select = (state, props) => ({
-  title: makeSelectTitleForUri(props.uri)(state),
-  thumbnail: makeSelectThumbnailForUri(props.uri)(state),
-  cover: makeSelectCoverForUri(props.uri)(state),
-  channelIsMine: makeSelectClaimIsMine(props.uri)(state),
-  page: selectCurrentChannelPage(state),
-  claim: makeSelectClaimForUri(props.uri)(state),
-  isSubscribed: makeSelectIsSubscribed(props.uri, true)(state),
-  blackListedOutpoints: selectBlackListedOutpoints(state),
-  subCount: makeSelectSubCountForUri(props.uri)(state),
-  pending: makeSelectClaimIsPending(props.uri)(state),
-  youtubeChannels: selectYoutubeChannels(state),
-  blockedChannels: selectModerationBlockList(state),
-  mutedChannels: selectMutedChannels(state),
-  unpublishedCollections: selectMyUnpublishedCollections(state),
-});
+const select = (state, props) => {
+  const claim = selectClaimForUri(state, props.uri);
+
+  return {
+    title: makeSelectTitleForUri(props.uri)(state),
+    thumbnail: makeSelectThumbnailForUri(props.uri)(state),
+    cover: makeSelectCoverForUri(props.uri)(state),
+    channelIsMine: selectClaimIsMine(state, claim),
+    page: selectCurrentChannelPage(state),
+    claim,
+    isSubscribed: makeSelectIsSubscribed(props.uri, true)(state),
+    blackListedOutpoints: selectBlackListedOutpoints(state),
+    subCount: selectSubCountForUri(state, props.uri),
+    pending: makeSelectClaimIsPending(props.uri)(state),
+    youtubeChannels: selectYoutubeChannels(state),
+    blockedChannels: selectModerationBlockList(state), // banlist
+    mutedChannels: selectMutedChannels(state),
+    unpublishedCollections: selectMyUnpublishedCollections(state),
+  };
+};
 
 const perform = (dispatch) => ({
   openModal: (modal, props) => dispatch(doOpenModal(modal, props)),
diff --git a/ui/page/collection/index.js b/ui/page/collection/index.js
index b6705e674..62585eafe 100644
--- a/ui/page/collection/index.js
+++ b/ui/page/collection/index.js
@@ -5,7 +5,7 @@ import CollectionPage from './view';
 import {
   makeSelectTitleForUri,
   makeSelectThumbnailForUri,
-  makeSelectClaimIsMine,
+  selectClaimIsMine,
   makeSelectClaimIsPending,
   makeSelectClaimForClaimId,
   makeSelectChannelForClaimUri,
@@ -20,11 +20,7 @@ import {
   makeSelectEditedCollectionForId,
 } from 'redux/selectors/collections';
 
-import {
-  doFetchItemsInCollection,
-  doCollectionDelete,
-  doCollectionEdit,
-} from 'redux/actions/collections';
+import { doFetchItemsInCollection, doCollectionDelete, doCollectionEdit } from 'redux/actions/collections';
 import { selectUser } from 'redux/selectors/user';
 
 const select = (state, props) => {
@@ -44,7 +40,7 @@ const select = (state, props) => {
     isResolvingCollection: makeSelectIsResolvingCollectionForId(collectionId)(state),
     title: makeSelectTitleForUri(uri)(state),
     thumbnail: makeSelectThumbnailForUri(uri)(state),
-    isMyClaim: makeSelectClaimIsMine(uri)(state), // or collection is mine?
+    isMyClaim: selectClaimIsMine(state, claim), // or collection is mine?
     isMyCollection: makeSelectCollectionIsMine(collectionId)(state),
     claimIsPending: makeSelectClaimIsPending(uri)(state),
     collectionHasEdits: Boolean(makeSelectEditedCollectionForId(collectionId)(state)),
diff --git a/ui/page/discover/index.js b/ui/page/discover/index.js
index 0d0823b74..55890537e 100644
--- a/ui/page/discover/index.js
+++ b/ui/page/discover/index.js
@@ -1,7 +1,7 @@
 import * as CS from 'constants/claim_search';
 import { connect } from 'react-redux';
 import { doResolveUri } from 'redux/actions/claims';
-import { makeSelectClaimForUri } from 'redux/selectors/claims';
+import { selectClaimForUri } from 'redux/selectors/claims';
 import * as SETTINGS from 'constants/settings';
 import { selectUserVerifiedEmail } from 'redux/selectors/user';
 import { selectFollowedTags } from 'redux/selectors/tags';
@@ -17,7 +17,7 @@ const select = (state, props) => {
   return {
     followedTags: selectFollowedTags(state),
     repostedUri: repostedUri,
-    repostedClaim: repostedUri ? makeSelectClaimForUri(repostedUri)(state) : null,
+    repostedClaim: repostedUri ? selectClaimForUri(state, repostedUri) : null,
     isAuthenticated: selectUserVerifiedEmail(state),
     tileLayout: makeSelectClientSetting(SETTINGS.TILE_LAYOUT)(state),
   };
diff --git a/ui/page/show/index.js b/ui/page/show/index.js
index 5f1ca151d..8c174e058 100644
--- a/ui/page/show/index.js
+++ b/ui/page/show/index.js
@@ -4,11 +4,11 @@ import { connect } from 'react-redux';
 import { withRouter } from 'react-router';
 import { PAGE_SIZE } from 'constants/claim';
 import {
-  makeSelectClaimForUri,
+  selectClaimForUri,
   makeSelectIsUriResolving,
   makeSelectTotalPagesForChannel,
   makeSelectTitleForUri,
-  makeSelectClaimIsMine,
+  selectClaimIsMine,
   makeSelectClaimIsPending,
 } from 'redux/selectors/claims';
 import {
@@ -62,7 +62,7 @@ const select = (state, props) => {
       props.history.replace(`/${path.slice(0, match.index)}`);
     }
   }
-  const claim = makeSelectClaimForUri(uri)(state);
+  const claim = selectClaimForUri(state, uri);
   const collectionId =
     urlParams.get(COLLECTIONS_CONSTS.COLLECTION_ID) ||
     (claim && claim.value_type === 'collection' && claim.claim_id) ||
@@ -76,7 +76,7 @@ const select = (state, props) => {
     totalPages: makeSelectTotalPagesForChannel(uri, PAGE_SIZE)(state),
     isSubscribed: makeSelectChannelInSubscriptions(uri)(state),
     title: makeSelectTitleForUri(uri)(state),
-    claimIsMine: makeSelectClaimIsMine(uri)(state),
+    claimIsMine: selectClaimIsMine(state, claim),
     claimIsPending: makeSelectClaimIsPending(uri)(state),
     collection: makeSelectCollectionForId(collectionId)(state),
     collectionId: collectionId,
diff --git a/ui/redux/actions/app.js b/ui/redux/actions/app.js
index 84da06b75..3420c9b69 100644
--- a/ui/redux/actions/app.js
+++ b/ui/redux/actions/app.js
@@ -9,7 +9,7 @@ import * as SHARED_PREFERENCES from 'constants/shared_preferences';
 import { DOMAIN } from 'config';
 import Lbry from 'lbry';
 import { doFetchChannelListMine, doFetchCollectionListMine, doCheckPendingClaims } from 'redux/actions/claims';
-import { makeSelectClaimForUri, makeSelectClaimIsMine, selectMyChannelClaims } from 'redux/selectors/claims';
+import { selectClaimForUri, selectClaimIsMineForUri, selectMyChannelClaims } from 'redux/selectors/claims';
 import { doFetchFileInfos } from 'redux/actions/file_info';
 import { doClearSupport, doBalanceSubscribe } from 'redux/actions/wallet';
 import { doClearPublish } from 'redux/actions/publish';
@@ -434,8 +434,9 @@ export function doToggleSearchExpanded() {
 export function doAnalyticsView(uri, timeToStart) {
   return (dispatch, getState) => {
     const state = getState();
-    const { txid, nout, claim_id: claimId } = makeSelectClaimForUri(uri)(state);
-    const claimIsMine = makeSelectClaimIsMine(uri)(state);
+    const claim = selectClaimForUri(state, uri);
+    const { txid, nout, claim_id: claimId } = claim;
+    const claimIsMine = selectClaimIsMineForUri(state, claim);
     const outpoint = `${txid}:${nout}`;
 
     if (claimIsMine) {
@@ -449,13 +450,13 @@ export function doAnalyticsView(uri, timeToStart) {
 export function doAnalyticsBuffer(uri, bufferData) {
   return (dispatch, getState) => {
     const state = getState();
-    const claim = makeSelectClaimForUri(uri)(state);
+    const claim = selectClaimForUri(state, uri);
     const user = selectUser(state);
     const {
       value: { video, audio, source },
     } = claim;
-    const timeAtBuffer = parseInt(bufferData.currentTime * 1000);
-    const bufferDuration = parseInt(bufferData.secondsToLoad * 1000);
+    const timeAtBuffer = parseInt(bufferData.currentTime ? bufferData.currentTime * 1000 : 0);
+    const bufferDuration = parseInt(bufferData.secondsToLoad ? bufferData.secondsToLoad * 1000 : 0);
     const fileDurationInSeconds = (video && video.duration) || (audio && audio.duration);
     const fileSize = source.size; // size in bytes
     const fileSizeInBits = fileSize * 8;
@@ -501,7 +502,7 @@ export function doSignIn() {
   return (dispatch, getState) => {
     const state = getState();
     const user = selectUser(state);
-    const notificationsEnabled = user.experimental_ui; // what is notifications?
+    const notificationsEnabled = user.experimental_ui;
 
     dispatch(doNotificationSocketConnect(notificationsEnabled));
 
diff --git a/ui/redux/actions/content.js b/ui/redux/actions/content.js
index 045987665..f8d593082 100644
--- a/ui/redux/actions/content.js
+++ b/ui/redux/actions/content.js
@@ -5,7 +5,12 @@ import * as MODALS from 'constants/modal_types';
 import { ipcRenderer } from 'electron';
 // @endif
 import { doOpenModal } from 'redux/actions/app';
-import { makeSelectClaimForUri, makeSelectClaimIsMine, makeSelectClaimWasPurchased } from 'redux/selectors/claims';
+import {
+  makeSelectClaimForUri,
+  selectClaimForUri,
+  makeSelectClaimIsMine,
+  makeSelectClaimWasPurchased,
+} from 'redux/selectors/claims';
 import {
   makeSelectFileInfoForUri,
   selectFileInfosByOutpoint,
@@ -216,7 +221,7 @@ export function doPlayUri(
 export function savePosition(uri: string, position: number) {
   return (dispatch: Dispatch, getState: () => any) => {
     const state = getState();
-    const claim = makeSelectClaimForUri(uri)(state);
+    const claim = selectClaimForUri(state, uri)(state);
     const { claim_id: claimId, txid, nout } = claim;
     const outpoint = `${txid}:${nout}`;
 
diff --git a/ui/redux/actions/file.js b/ui/redux/actions/file.js
index 41cf1a2bb..e73177e35 100644
--- a/ui/redux/actions/file.js
+++ b/ui/redux/actions/file.js
@@ -5,7 +5,7 @@ import * as ABANDON_STATES from 'constants/abandon_states';
 import { shell } from 'electron';
 // @endif
 import Lbry from 'lbry';
-import { makeSelectClaimForUri } from 'redux/selectors/claims';
+import { selectClaimForUri } from 'redux/selectors/claims';
 import { doAbandonClaim } from 'redux/actions/claims';
 import { batchActions } from 'util/batch-actions';
 
@@ -71,7 +71,7 @@ export function doDeleteFileAndMaybeGoBack(
     const state = getState();
     const playingUri = selectPlayingUri(state);
     const { outpoint } = makeSelectFileInfoForUri(uri)(state) || '';
-    const { nout, txid } = makeSelectClaimForUri(uri)(state);
+    const { nout, txid } = selectClaimForUri(state, uri);
     const claimOutpoint = `${txid}:${nout}`;
     const actions = [];
 
@@ -105,7 +105,7 @@ export function doDeleteFileAndMaybeGoBack(
 export function doFileGet(uri: string, saveFile: boolean = true, onSuccess?: (GetResponse) => any) {
   return (dispatch: Dispatch, getState: () => any) => {
     const state = getState();
-    const { nout, txid } = makeSelectClaimForUri(uri)(state);
+    const { nout, txid } = selectClaimForUri(state, uri);
     const outpoint = `${txid}:${nout}`;
 
     dispatch({
diff --git a/ui/redux/actions/reactions.js b/ui/redux/actions/reactions.js
index 51d2ac1a4..8c3d90eb3 100644
--- a/ui/redux/actions/reactions.js
+++ b/ui/redux/actions/reactions.js
@@ -3,7 +3,7 @@ import { Lbryio } from 'lbryinc';
 import * as ACTIONS from 'constants/action_types';
 import * as REACTION_TYPES from 'constants/reactions';
 import { makeSelectMyReactionForUri } from 'redux/selectors/reactions';
-import { makeSelectClaimForUri } from 'redux/selectors/claims';
+import { selectClaimForUri } from 'redux/selectors/claims';
 
 export const doFetchReactions = (claimId: string) => (dispatch: Dispatch) => {
   dispatch({ type: ACTIONS.REACTIONS_LIST_STARTED });
@@ -20,7 +20,7 @@ export const doFetchReactions = (claimId: string) => (dispatch: Dispatch) => {
 export const doReactionLike = (uri: string) => (dispatch: Dispatch, getState: GetState) => {
   const state = getState();
   const myReaction = makeSelectMyReactionForUri(uri)(state);
-  const claim = makeSelectClaimForUri(uri)(state);
+  const claim = selectClaimForUri(state, uri);
   const claimId = claim.claim_id;
   const shouldRemove = myReaction === REACTION_TYPES.LIKE;
 
@@ -46,7 +46,7 @@ export const doReactionLike = (uri: string) => (dispatch: Dispatch, getState: Ge
 export const doReactionDislike = (uri: string) => (dispatch: Dispatch, getState: GetState) => {
   const state = getState();
   const myReaction = makeSelectMyReactionForUri(uri)(state);
-  const claim = makeSelectClaimForUri(uri)(state);
+  const claim = selectClaimForUri(state, uri);
   const claimId = claim.claim_id;
   const shouldRemove = myReaction === REACTION_TYPES.DISLIKE;
 
diff --git a/ui/redux/actions/search.js b/ui/redux/actions/search.js
index 2a3de1afe..dfd9c724a 100644
--- a/ui/redux/actions/search.js
+++ b/ui/redux/actions/search.js
@@ -1,7 +1,7 @@
 // @flow
 import * as ACTIONS from 'constants/action_types';
 import { selectShowMatureContent } from 'redux/selectors/settings';
-import { makeSelectClaimForUri, makeSelectClaimIsNsfw } from 'redux/selectors/claims';
+import { selectClaimForUri, makeSelectClaimIsNsfw } from 'redux/selectors/claims';
 import { doResolveUris } from 'redux/actions/claims';
 import { buildURI, isURIValid } from 'util/lbryURI';
 import { batchActions } from 'util/batch-actions';
@@ -131,7 +131,7 @@ export const doUpdateSearchOptions = (newOptions: SearchOptions, additionalOptio
 
 export const doFetchRecommendedContent = (uri: string) => (dispatch: Dispatch, getState: GetState) => {
   const state = getState();
-  const claim = makeSelectClaimForUri(uri)(state);
+  const claim = selectClaimForUri(state, uri);
   const matureEnabled = selectShowMatureContent(state);
   const claimIsMature = makeSelectClaimIsNsfw(uri)(state);
 
diff --git a/ui/redux/actions/user.js b/ui/redux/actions/user.js
index 701c36e5a..0935027d3 100644
--- a/ui/redux/actions/user.js
+++ b/ui/redux/actions/user.js
@@ -1,5 +1,5 @@
 import Lbry from 'lbry';
-import { makeSelectClaimForUri } from 'redux/selectors/claims';
+import { selectClaimForUri } from 'redux/selectors/claims';
 import { doFetchChannelListMine } from 'redux/actions/claims';
 import { isURIValid, normalizeURI } from 'util/lbryURI';
 import { batchActions } from 'util/batch-actions';
@@ -657,7 +657,7 @@ export function doUserSetReferrer(referrer, shouldClaim) {
     const isValid = isURIValid(referrer);
     if (isValid) {
       const uri = normalizeURI(referrer);
-      claim = makeSelectClaimForUri(uri)(getState());
+      claim = selectClaimForUri(getState(), uri);
       if (!claim) {
         try {
           const response = await Lbry.resolve({ urls: [uri] });
diff --git a/ui/redux/selectors/app.js b/ui/redux/selectors/app.js
index daea35ac1..aef96c158 100644
--- a/ui/redux/selectors/app.js
+++ b/ui/redux/selectors/app.js
@@ -1,5 +1,5 @@
 import { createSelector } from 'reselect';
-import { selectClaimsById, selectMyChannelClaims, makeSelectStakedLevelForChannelUri } from 'redux/selectors/claims';
+import { selectClaimsById, selectMyChannelClaims, selectTotalStakedAmountForChannelUri } from 'redux/selectors/claims';
 
 export const selectState = (state) => state.app || {};
 
@@ -127,7 +127,7 @@ export const selectActiveChannelStakedLevel = createSelector(
     }
 
     const uri = activeChannelClaim.permanent_url;
-    const stakedLevel = makeSelectStakedLevelForChannelUri(uri)(state);
+    const stakedLevel = selectTotalStakedAmountForChannelUri(state, uri)(state);
 
     return stakedLevel;
   }
diff --git a/ui/redux/selectors/claims.js b/ui/redux/selectors/claims.js
index 45f12936e..fb986fe1f 100644
--- a/ui/redux/selectors/claims.js
+++ b/ui/redux/selectors/claims.js
@@ -8,7 +8,7 @@ import * as CLAIM from 'constants/claim';
 
 type State = { claims: any };
 
-const selectState = (state) => state.claims || {};
+const selectState = (state: State) => state.claims || {};
 
 export const selectById = (state: State) => selectState(state).byId || {};
 export const selectPendingClaimsById = (state: State) => selectState(state).pendingById || {};
@@ -18,16 +18,11 @@ export const selectClaimsById = createSelector(selectById, selectPendingClaimsBy
 });
 
 export const selectClaimIdsByUri = (state: State) => selectState(state).claimsByUri || {};
-
-export const selectCurrentChannelPage = createSelector(selectState, (state) => state.currentChannelPage || 1);
-
-export const selectCreatingChannel = createSelector(selectState, (state) => state.creatingChannel);
-
-export const selectCreateChannelError = createSelector(selectState, (state) => state.createChannelError);
-
-export const selectRepostLoading = createSelector(selectState, (state) => state.repostLoading);
-
-export const selectRepostError = createSelector(selectState, (state) => state.repostError);
+export const selectCurrentChannelPage = (state: State) => selectState(state).currentChannelPage || 1;
+export const selectCreatingChannel = (state: State) => selectState(state).creatingChannel;
+export const selectCreateChannelError = (state: State) => selectState(state).createChannelError;
+export const selectRepostLoading = (state: State) => selectState(state).repostLoading;
+export const selectRepostError = (state: State) => selectState(state).repostError;
 
 export const selectClaimsByUri = createSelector(selectClaimIdsByUri, selectClaimsById, (byUri, byId) => {
   const claims = {};
@@ -48,6 +43,21 @@ export const selectClaimsByUri = createSelector(selectClaimIdsByUri, selectClaim
   return claims;
 });
 
+/**
+ * Returns the claim with the specified ID. The claim could be undefined if does
+ * not exist or have not fetched. Take note of the second parameter, which means
+ * an inline function or helper would be required when used as an input to
+ * 'createSelector'.
+ *
+ * @param state
+ * @param claimId
+ * @returns {*}
+ */
+export const selectClaimWithId = (state: State, claimId: string) => {
+  const byId = selectClaimsById(state);
+  return byId[claimId];
+};
+
 export const selectAllClaimsByChannel = createSelector(selectState, (state) => state.paginatedClaimsByChannel || {});
 
 export const selectPendingIds = createSelector(selectState, (state) => Object.keys(state.pendingById) || []);
@@ -69,10 +79,9 @@ export const makeSelectClaimIdIsPending = (claimId: string) =>
     return Boolean(pendingById[claimId]);
   });
 
-export const makeSelectClaimIdForUri = (uri: string) =>
-  createSelector(selectClaimIdsByUri, (claimIds) => claimIds[uri]);
+export const selectClaimIdForUri = (state: State, uri: string) => selectClaimIdsByUri(state)[uri];
 
-export const selectReflectingById = createSelector(selectState, (state) => state.reflectingById);
+export const selectReflectingById = (state: State) => selectState(state).reflectingById;
 
 export const makeSelectClaimForClaimId = (claimId: string) => createSelector(selectClaimsById, (byId) => byId[claimId]);
 
@@ -85,7 +94,8 @@ export const selectClaimForUri = createCachedSelector(
     const validUri = isURIValid(uri);
 
     if (validUri && byUri) {
-      const claimId = uri && byUri[normalizeURI(uri)];
+      const normalizedUri = normalizeURI(uri);
+      const claimId = uri && byUri[normalizedUri];
       const claim = byId[claimId];
 
       // Make sure to return the claim as is so apps can check if it's been resolved before (null) or still needs to be resolved (undefined)
@@ -102,7 +112,7 @@ export const selectClaimForUri = createCachedSelector(
 
         return {
           ...repostedClaim,
-          repost_url: normalizeURI(uri),
+          repost_url: normalizedUri,
           repost_channel_url: channelUrl,
           repost_bid_amount: claim && claim.meta && claim.meta.effective_amount,
         };
@@ -111,14 +121,16 @@ export const selectClaimForUri = createCachedSelector(
       }
     }
   }
-)((state, uri, returnRepost = true) => `${uri}:${returnRepost ? '1' : '0'}`);
+)((state, uri, returnRepost = true) => `${String(uri)}:${returnRepost ? '1' : '0'}`);
 
+// Note: this is deprecated. Use "selectClaimForUri(state, uri)" instead.
 export const makeSelectClaimForUri = (uri: string, returnRepost: boolean = true) =>
   createSelector(selectClaimIdsByUri, selectClaimsById, (byUri, byId) => {
     const validUri = isURIValid(uri);
 
     if (validUri && byUri) {
-      const claimId = uri && byUri[normalizeURI(uri)];
+      const normalizedUri = normalizeURI(uri);
+      const claimId = uri && byUri[normalizedUri];
       const claim = byId[claimId];
 
       // Make sure to return the claim as is so apps can check if it's been resolved before (null) or still needs to be resolved (undefined)
@@ -135,7 +147,7 @@ export const makeSelectClaimForUri = (uri: string, returnRepost: boolean = true)
 
         return {
           ...repostedClaim,
-          repost_url: normalizeURI(uri),
+          repost_url: normalizedUri,
           repost_channel_url: channelUrl,
           repost_bid_amount: claim && claim.meta && claim.meta.effective_amount,
         };
@@ -145,6 +157,9 @@ export const makeSelectClaimForUri = (uri: string, returnRepost: boolean = true)
     }
   });
 
+// Returns your claim IDs without handling pending and abandoned claims.
+export const selectMyClaimIdsRaw = (state: State) => selectState(state).myClaims;
+
 export const selectMyClaimsRaw = createSelector(selectState, selectClaimsById, (state, byId) => {
   const ids = state.myClaims;
   if (!ids) {
@@ -161,7 +176,10 @@ export const selectMyClaimsRaw = createSelector(selectState, selectClaimsById, (
   return claims;
 });
 
-export const selectAbandoningIds = createSelector(selectState, (state) => Object.keys(state.abandoningById || {}));
+export const selectAbandoningById = (state: State) => selectState(state).abandoningById || {};
+export const selectAbandoningIds = createSelector(selectAbandoningById, (abandoningById) =>
+  Object.keys(abandoningById)
+);
 
 export const makeSelectAbandoningClaimById = (claimId: string) =>
   createSelector(selectAbandoningIds, (ids) => ids.includes(claimId));
@@ -173,12 +191,63 @@ export const makeSelectIsAbandoningClaimForUri = (uri: string) =>
   });
 
 export const selectMyActiveClaims = createSelector(
-  selectMyClaimsRaw,
+  selectMyClaimIdsRaw,
   selectAbandoningIds,
-  (claims, abandoningIds) =>
-    new Set(claims && claims.map((claim) => claim.claim_id).filter((claimId) => !abandoningIds.includes(claimId)))
+  (myClaimIds, abandoningIds) => {
+    return new Set(myClaimIds && myClaimIds.filter((claimId) => !abandoningIds.includes(claimId)));
+  }
 );
 
+// Helper for 'selectClaimIsMineForUri'.
+// Returns undefined string if unable to normalize or is not valid.
+const selectNormalizedAndVerifiedUri = createCachedSelector(
+  (state, rawUri) => rawUri,
+  (rawUri) => {
+    try {
+      const uri = normalizeURI(rawUri);
+      if (isURIValid(uri)) {
+        return uri;
+      }
+    } catch (e) {}
+
+    return undefined;
+  }
+)((state, rawUri) => String(rawUri));
+
+export const selectClaimIsMine = (state: State, claim: ?Claim) => {
+  if (claim) {
+    // The original code seems to imply that 'is_my_output' could be false even
+    // when it is yours and there is a need to double-check with 'myActiveClaims'.
+    // I'm retaining that logic. Otherwise, we could have just return
+    // is_my_output directly when it is defined and skip the fallback.
+    if (claim.is_my_output) {
+      return true;
+    } else {
+      // 'is_my_output' is false or undefined.
+      const myActiveClaims = selectMyActiveClaims(state);
+      return claim.claim_id && myActiveClaims.has(claim.claim_id);
+    }
+  } else {
+    return false;
+  }
+};
+
+export const selectClaimIsMineForUri = (state: State, rawUri: string) => {
+  // Not memoizing this selector because:
+  // (1) The workload is somewhat lightweight.
+  // (2) Since it depends on 'selectClaimsByUri', memoization won't work anyway
+  // because the array is constantly invalidated.
+
+  const uri = selectNormalizedAndVerifiedUri(state, rawUri);
+  if (!uri) {
+    return false;
+  }
+
+  const claimsByUri = selectClaimsByUri(state);
+  return selectClaimIsMine(state, claimsByUri && claimsByUri[uri]);
+};
+
+// DEPRECATED - use selectClaimIsMineForUri instead.
 export const makeSelectClaimIsMine = (rawUri: string) => {
   let uri;
   try {
@@ -198,15 +267,11 @@ export const makeSelectClaimIsMine = (rawUri: string) => {
   });
 };
 
-export const selectMyPurchases = createSelector(selectState, (state) => state.myPurchases);
-
-export const selectPurchaseUriSuccess = createSelector(selectState, (state) => state.purchaseUriSuccess);
-
-export const selectMyPurchasesCount = createSelector(selectState, (state) => state.myPurchasesPageTotalResults);
-
-export const selectIsFetchingMyPurchases = createSelector(selectState, (state) => state.fetchingMyPurchases);
-
-export const selectFetchingMyPurchasesError = createSelector(selectState, (state) => state.fetchingMyPurchasesError);
+export const selectMyPurchases = (state: State) => selectState(state).myPurchases;
+export const selectPurchaseUriSuccess = (state: State) => selectState(state).purchaseUriSuccess;
+export const selectMyPurchasesCount = (state: State) => selectState(state).myPurchasesPageTotalResults;
+export const selectIsFetchingMyPurchases = (state: State) => selectState(state).fetchingMyPurchases;
+export const selectFetchingMyPurchasesError = (state: State) => selectState(state).fetchingMyPurchasesError;
 
 export const makeSelectMyPurchasesForPage = (query: ?string, page: number = 1) =>
   createSelector(
@@ -270,7 +335,7 @@ export const makeSelectTotalPagesInChannelSearch = (uri: string) =>
 export const selectMetadataForUri = createCachedSelector(selectClaimForUri, (claim, uri) => {
   const metadata = claim && claim.value;
   return metadata || (claim === undefined ? undefined : null);
-})((state, uri) => uri);
+})((state, uri) => String(uri));
 
 export const makeSelectMetadataForUri = (uri: string) =>
   createSelector(makeSelectClaimForUri(uri), (claim) => {
@@ -303,7 +368,7 @@ export const selectDateForUri = createCachedSelector(
     const dateObj = new Date(timestamp);
     return dateObj;
   }
-)((state, uri) => uri);
+)((state, uri) => String(uri));
 
 export const makeSelectAmountForUri = (uri: string) =>
   createSelector(makeSelectClaimForUri(uri), (claim) => {
@@ -335,7 +400,7 @@ export const makeSelectCoverForUri = (uri: string) =>
     return cover && cover.url ? cover.url.trim().replace(/^http:\/\//i, 'https://') : undefined;
   });
 
-export const selectIsFetchingClaimListMine = createSelector(selectState, (state) => state.isFetchingClaimListMine);
+export const selectIsFetchingClaimListMine = (state: State) => selectState(state).isFetchingClaimListMine;
 
 export const selectMyClaimsPage = createSelector(selectState, (state) => state.myClaimsPageResults || []);
 
@@ -346,12 +411,8 @@ export const selectMyClaimsPageNumber = createSelector(
   (state) => (state.txoPage && state.txoPage.page) || 1
 );
 
-export const selectMyClaimsPageItemCount = createSelector(selectState, (state) => state.myClaimsPageTotalResults || 1);
-
-export const selectFetchingMyClaimsPageError = createSelector(
-  selectState,
-  (state) => state.fetchingClaimListMinePageError
-);
+export const selectMyClaimsPageItemCount = (state: State) => selectState(state).myClaimsPageTotalResults || 1;
+export const selectFetchingMyClaimsPageError = (state: State) => selectState(state).fetchingClaimListMinePageError;
 
 export const selectMyClaims = createSelector(
   selectMyActiveClaims,
@@ -403,18 +464,31 @@ export const selectMyClaimsOutpoints = createSelector(selectMyClaims, (myClaims)
   return outpoints;
 });
 
-export const selectFetchingMyChannels = createSelector(selectState, (state) => state.fetchingMyChannels);
+export const selectFetchingMyChannels = (state: State) => selectState(state).fetchingMyChannels;
+export const selectFetchingMyCollections = (state: State) => selectState(state).fetchingMyCollections;
 
-export const selectFetchingMyCollections = createSelector(selectState, (state) => state.fetchingMyCollections);
+export const selectMyChannelClaimIds = (state: State) => selectState(state).myChannelClaims;
 
-export const selectMyChannelClaims = createSelector(selectState, selectClaimsById, (state, byId) => {
-  const ids = state.myChannelClaims;
-  if (!ids) {
-    return ids;
+export const selectMyChannelClaims = createSelector(selectMyChannelClaimIds, (myChannelClaimIds) => {
+  if (!myChannelClaimIds) {
+    return myChannelClaimIds;
   }
 
+  if (!window || !window.store) {
+    return undefined;
+  }
+
+  // Note: Grabbing the store and running the selector this way is anti-pattern,
+  // but it is _needed_ and works only because we know for sure that 'byId[]'
+  // will be populated with the same claims as when 'myChannelClaimIds' is populated.
+  // If we put 'state' or 'byId' as the input selector, it essentially
+  // recalculates every time. Putting 'state' as input to createSelector() is
+  // always wrong from a memoization standpoint.
+  const state = window.store.getState();
+  const byId = selectClaimsById(state);
+
   const claims = [];
-  ids.forEach((id) => {
+  myChannelClaimIds.forEach((id) => {
     if (byId[id]) {
       // I'm not sure why this check is necessary, but it ought to be a quick fix for https://github.com/lbryio/lbry-desktop/issues/544
       claims.push(byId[id]);
@@ -428,16 +502,21 @@ export const selectMyChannelUrls = createSelector(selectMyChannelClaims, (claims
   claims ? claims.map((claim) => claim.canonical_url || claim.permanent_url) : undefined
 );
 
-export const selectMyCollectionIds = createSelector(selectState, (state) => state.myCollectionClaims);
+export const selectHasChannels = (state: State) => {
+  const myChannelClaimIds = selectMyChannelClaimIds(state);
+  return myChannelClaimIds ? myChannelClaimIds.length > 0 : false;
+};
+
+export const selectMyCollectionIds = (state: State) => selectState(state).myCollectionClaims;
 
 export const selectResolvingUris = createSelector(selectState, (state) => state.resolvingUris || []);
 
-export const selectChannelImportPending = createSelector(selectState, (state) => state.pendingChannelImport);
+export const selectChannelImportPending = (state: State) => selectState(state).pendingChannelImport;
 
 export const makeSelectIsUriResolving = (uri: string) =>
   createSelector(selectResolvingUris, (resolvingUris) => resolvingUris && resolvingUris.indexOf(uri) !== -1);
 
-export const selectPlayingUri = createSelector(selectState, (state) => state.playingUri);
+export const selectPlayingUri = (state: State) => selectState(state).playingUri;
 
 export const selectChannelClaimCounts = createSelector(selectState, (state) => state.channelClaimCounts || {});
 
@@ -541,7 +620,7 @@ export const makeSelectMyChannelPermUrlForName = (name: string) =>
 
 export const selectTagsForUri = createCachedSelector(selectMetadataForUri, (metadata: ?GenericMetadata) => {
   return (metadata && metadata.tags) || [];
-})((state, uri) => uri);
+})((state, uri) => String(uri));
 
 export const makeSelectTagsForUri = (uri: string) =>
   createSelector(makeSelectMetadataForUri(uri), (metadata: ?GenericMetadata) => {
@@ -592,9 +671,8 @@ export const makeSelectSupportsForUri = (uri: string) =>
     return total;
   });
 
-export const selectUpdatingChannel = createSelector(selectState, (state) => state.updatingChannel);
-
-export const selectUpdateChannelError = createSelector(selectState, (state) => state.updateChannelError);
+export const selectUpdatingChannel = (state: State) => selectState(state).updatingChannel;
+export const selectUpdateChannelError = (state: State) => selectState(state).updateChannelError;
 
 export const makeSelectReflectingClaimForUri = (uri: string) =>
   createSelector(selectClaimIdsByUri, selectReflectingById, (claimIdsByUri, reflectingById) => {
@@ -638,39 +716,34 @@ export const makeSelectClaimIsStreamPlaceholder = (uri: string) =>
     return Boolean(claim.value_type === 'stream' && !claim.value.source);
   });
 
-export const makeSelectTotalStakedAmountForChannelUri = (uri: string) =>
-  createSelector(makeSelectClaimForUri(uri), (claim) => {
-    if (!claim || !claim.amount || !claim.meta || !claim.meta.support_amount) {
-      return 0;
-    }
+export const selectTotalStakedAmountForChannelUri = createCachedSelector(selectClaimForUri, (claim) => {
+  if (!claim || !claim.amount || !claim.meta || !claim.meta.support_amount) {
+    return 0;
+  }
 
-    return parseFloat(claim.amount) + parseFloat(claim.meta.support_amount) || 0;
-  });
+  return parseFloat(claim.amount) + parseFloat(claim.meta.support_amount) || 0;
+})((state, uri) => String(uri));
 
-export const makeSelectStakedLevelForChannelUri = (uri: string) =>
-  createSelector(makeSelectTotalStakedAmountForChannelUri(uri), (amount) => {
-    let level = 1;
-    switch (true) {
-      case amount >= CLAIM.LEVEL_2_STAKED_AMOUNT && amount < CLAIM.LEVEL_3_STAKED_AMOUNT:
-        level = 2;
-        break;
-      case amount >= CLAIM.LEVEL_3_STAKED_AMOUNT && amount < CLAIM.LEVEL_4_STAKED_AMOUNT:
-        level = 3;
-        break;
-      case amount >= CLAIM.LEVEL_4_STAKED_AMOUNT && amount < CLAIM.LEVEL_5_STAKED_AMOUNT:
-        level = 4;
-        break;
-      case amount >= CLAIM.LEVEL_5_STAKED_AMOUNT:
-        level = 5;
-        break;
-    }
-    return level;
-  });
+export const selectStakedLevelForChannelUri = createCachedSelector(selectTotalStakedAmountForChannelUri, (amount) => {
+  let level = 1;
+  switch (true) {
+    case amount >= CLAIM.LEVEL_2_STAKED_AMOUNT && amount < CLAIM.LEVEL_3_STAKED_AMOUNT:
+      level = 2;
+      break;
+    case amount >= CLAIM.LEVEL_3_STAKED_AMOUNT && amount < CLAIM.LEVEL_4_STAKED_AMOUNT:
+      level = 3;
+      break;
+    case amount >= CLAIM.LEVEL_4_STAKED_AMOUNT && amount < CLAIM.LEVEL_5_STAKED_AMOUNT:
+      level = 4;
+      break;
+    case amount >= CLAIM.LEVEL_5_STAKED_AMOUNT:
+      level = 5;
+      break;
+  }
+  return level;
+})((state, uri) => String(uri));
 
-export const selectUpdatingCollection = createSelector(selectState, (state) => state.updatingCollection);
-
-export const selectUpdateCollectionError = createSelector(selectState, (state) => state.updateCollectionError);
-
-export const selectCreatingCollection = createSelector(selectState, (state) => state.creatingCollection);
-
-export const selectCreateCollectionError = createSelector(selectState, (state) => state.createCollectionError);
+export const selectUpdatingCollection = (state: State) => selectState(state).updatingCollection;
+export const selectUpdateCollectionError = (state: State) => selectState(state).updateCollectionError;
+export const selectCreatingCollection = (state: State) => selectState(state).creatingCollection;
+export const selectCreateCollectionError = (state: State) => selectState(state).createCollectionError;
diff --git a/ui/redux/selectors/comments.js b/ui/redux/selectors/comments.js
index bc53eb785..4ced61c4f 100644
--- a/ui/redux/selectors/comments.js
+++ b/ui/redux/selectors/comments.js
@@ -4,14 +4,15 @@ import { createCachedSelector } from 're-reselect';
 import { selectMutedChannels } from 'redux/selectors/blocked';
 import { selectShowMatureContent } from 'redux/selectors/settings';
 import { selectBlacklistedOutpointMap, selectFilteredOutpointMap } from 'lbryinc';
-import { selectClaimsById, selectMyActiveClaims } from 'redux/selectors/claims';
+import { selectClaimsById, selectMyActiveClaims, selectClaimIdForUri } from 'redux/selectors/claims';
 import { isClaimNsfw } from 'util/claim';
 
-type State = { comments: CommentsState };
+type State = { comments: CommentsState, claims: any };
 
 const selectState = (state) => state.comments || {};
 
 export const selectCommentsById = (state: State) => selectState(state).commentById || {};
+export const selectCommentIdsByClaimId = (state: State) => selectState(state).byId;
 export const selectIsFetchingComments = (state: State) => selectState(state).isLoading;
 export const selectIsFetchingCommentsById = (state: State) => selectState(state).isLoadingById;
 export const selectIsFetchingCommentsByParentId = (state: State) => selectState(state).isLoadingByParentId;
@@ -173,6 +174,12 @@ export const selectRepliesByParentId = createSelector(selectState, selectComment
 
 export const selectLinkedCommentAncestors = (state: State) => selectState(state).linkedCommentAncestors;
 
+export const selectCommentIdsForUri = (state: State, uri: string) => {
+  const claimId = selectClaimIdForUri(state, uri);
+  const commentIdsByClaimId = selectCommentIdsByClaimId(state);
+  return commentIdsByClaimId[claimId];
+};
+
 export const makeSelectCommentIdsForUri = (uri: string) =>
   createSelector(selectState, selectCommentsByUri, selectClaimsById, (state, byUri) => {
     const claimId = byUri[uri];