diff --git a/flow-typed/livestream.js b/flow-typed/livestream.js
index 936339428..0eaf2757e 100644
--- a/flow-typed/livestream.js
+++ b/flow-typed/livestream.js
@@ -21,17 +21,6 @@ declare type LivestreamReplayItem = {
 }
 declare type LivestreamReplayData = Array<LivestreamReplayItem>;
 
-declare type CurrentLiveClaim = {
-  claimId: string | null,
-  claimUri: string | null,
-}
-
-declare type LivestreamChannelStatus = {
-  channelId: null | string,
-  isBroadcasting: boolean,
-  liveClaim: CurrentLiveClaim,
-}
-
 declare type LivestreamState = {
   fetchingById: {},
   viewersById: {},
@@ -39,8 +28,7 @@ declare type LivestreamState = {
   activeLivestreams: ?LivestreamInfo,
   activeLivestreamsLastFetchedDate: number,
   activeLivestreamsLastFetchedOptions: {},
-
-  currentChannelStatus: LivestreamChannelStatus,
+  activeLivestreamInitialized: boolean,
 }
 
 declare type LivestreamInfo = {
diff --git a/ui/component/channelContent/index.js b/ui/component/channelContent/index.js
index 61f3a546f..76f6c715d 100644
--- a/ui/component/channelContent/index.js
+++ b/ui/component/channelContent/index.js
@@ -14,8 +14,8 @@ import { withRouter } from 'react-router';
 import { selectUserVerifiedEmail } from 'redux/selectors/user';
 import { selectClientSetting, selectShowMatureContent } from 'redux/selectors/settings';
 import { doFetchActiveLivestream } from 'redux/actions/livestream';
-import { selectCurrentChannelStatus } from 'redux/selectors/livestream';
-
+import { selectActiveLivestreamForChannel, selectActiveLivestreamInitialized } from 'redux/selectors/livestream';
+import { getChannelIdFromClaim } from 'util/claim';
 import ChannelContent from './view';
 
 const select = (state, props) => {
@@ -23,6 +23,7 @@ const select = (state, props) => {
   const urlParams = new URLSearchParams(search);
   const page = urlParams.get('page') || 0;
   const claim = props.uri && selectClaimForUri(state, props.uri);
+  const channelClaimId = getChannelIdFromClaim(claim);
 
   return {
     pageOfClaimsInChannel: makeSelectClaimsInChannelForPage(props.uri, page)(state),
@@ -34,7 +35,8 @@ const select = (state, props) => {
     isAuthenticated: selectUserVerifiedEmail(state),
     showMature: selectShowMatureContent(state),
     tileLayout: selectClientSetting(state, SETTINGS.TILE_LAYOUT),
-    currentChannelStatus: selectCurrentChannelStatus(state),
+    activeLivestreamForChannel: selectActiveLivestreamForChannel(state, channelClaimId),
+    activeLivestreamInitialized: selectActiveLivestreamInitialized(state),
   };
 };
 
diff --git a/ui/component/channelContent/view.jsx b/ui/component/channelContent/view.jsx
index 49c1afa47..52f692d2c 100644
--- a/ui/component/channelContent/view.jsx
+++ b/ui/component/channelContent/view.jsx
@@ -38,7 +38,8 @@ type Props = {
   claimType: string,
   empty?: string,
   doFetchActiveLivestream: (string) => void,
-  currentChannelStatus: LivestreamChannelStatus,
+  activeLivestreamForChannel: any,
+  activeLivestreamInitialized: boolean,
 };
 
 function ChannelContent(props: Props) {
@@ -59,7 +60,8 @@ function ChannelContent(props: Props) {
     claimType,
     empty,
     doFetchActiveLivestream,
-    currentChannelStatus,
+    activeLivestreamForChannel,
+    activeLivestreamInitialized,
   } = props;
   // const claimsInChannel = (claim && claim.meta.claims_in_channel) || 0;
   const claimsInChannel = 9999;
@@ -252,8 +254,8 @@ function ChannelContent(props: Props) {
     setSearchResults(null);
   }, [url]);
 
-  const [isInitialized, setIsInitialized] = React.useState(false);
-  const [isChannelBroadcasting, setIsChannelBroadcasting] = React.useState(false);
+  const isInitialized = Boolean(activeLivestreamForChannel) || activeLivestreamInitialized;
+  const isChannelBroadcasting = Boolean(activeLivestreamForChannel);
 
   // Find out current channels status + active live claim.
   React.useEffect(() => {
@@ -262,14 +264,6 @@ function ChannelContent(props: Props) {
     return () => clearInterval(intervalId);
   }, [claimId, doFetchActiveLivestream]);
 
-  React.useEffect(() => {
-    const initialized = currentChannelStatus.channelId === claimId;
-    setIsInitialized(initialized);
-    if (initialized) {
-      setIsChannelBroadcasting(currentChannelStatus.isBroadcasting);
-    }
-  }, [currentChannelStatus, claimId]);
-
   const showScheduledLiveStreams = claimType !== 'collection'; // ie. not on the playlist page.
 
   return (
@@ -279,7 +273,7 @@ function ChannelContent(props: Props) {
       )}
 
       {!fetching && isInitialized && isChannelBroadcasting && !isChannelEmpty && (
-        <LivestreamLink claimUri={currentChannelStatus.liveClaim.claimUri} />
+        <LivestreamLink claimUri={activeLivestreamForChannel.claimUri} />
       )}
 
       {!fetching && showScheduledLiveStreams && (
@@ -287,7 +281,7 @@ function ChannelContent(props: Props) {
           channelIds={[claimId]}
           tileLayout={tileLayout}
           liveUris={
-            isChannelBroadcasting && currentChannelStatus.liveClaim ? [currentChannelStatus.liveClaim.claimUri] : []
+            isChannelBroadcasting && activeLivestreamForChannel.claimUri ? [activeLivestreamForChannel.claimUri] : []
           }
         />
       )}
diff --git a/ui/component/claimListDiscover/context.js b/ui/component/claimListDiscover/context.js
deleted file mode 100644
index 22eaf5354..000000000
--- a/ui/component/claimListDiscover/context.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import { createContext } from 'react';
-
-const ClaimListDiscoverContext = createContext();
-
-export default ClaimListDiscoverContext;
diff --git a/ui/component/claimPreviewSubtitle/index.js b/ui/component/claimPreviewSubtitle/index.js
index 513f8d444..fcf3c65b6 100644
--- a/ui/component/claimPreviewSubtitle/index.js
+++ b/ui/component/claimPreviewSubtitle/index.js
@@ -5,7 +5,6 @@ import { doClearPublish, doPrepareEdit } from 'redux/actions/publish';
 import { push } from 'connected-react-router';
 import ClaimPreviewSubtitle from './view';
 import { doFetchSubCount, selectSubCountForUri } from 'lbryinc';
-import { selectIsActiveLivestreamForUri } from 'redux/selectors/livestream';
 
 const select = (state, props) => {
   const claim = selectClaimForUri(state, props.uri);
@@ -16,7 +15,6 @@ const select = (state, props) => {
     pending: makeSelectClaimIsPending(props.uri)(state),
     isLivestream,
     subCount: isChannel ? selectSubCountForUri(state, props.uri) : 0,
-    isLivestreamActive: isLivestream && selectIsActiveLivestreamForUri(state, props.uri),
   };
 };
 
diff --git a/ui/component/claimPreviewSubtitle/view.jsx b/ui/component/claimPreviewSubtitle/view.jsx
index 5c2f2e5eb..c12fca6a0 100644
--- a/ui/component/claimPreviewSubtitle/view.jsx
+++ b/ui/component/claimPreviewSubtitle/view.jsx
@@ -1,13 +1,12 @@
 // @flow
 import { ENABLE_NO_SOURCE_CLAIMS } from 'config';
-import React, { useContext } from 'react';
+import React from 'react';
 import UriIndicator from 'component/uriIndicator';
 import DateTime from 'component/dateTime';
+import LivestreamDateTime from 'component/livestreamDateTime';
 import Button from 'component/button';
 import FileViewCountInline from 'component/fileViewCountInline';
 import { parseURI } from 'util/lbryURI';
-import ClaimListDiscoverContext from 'component/claimListDiscover/context';
-import moment from 'moment';
 
 type Props = {
   uri: string,
@@ -18,12 +17,11 @@ type Props = {
   isLivestream: boolean,
   fetchSubCount: (string) => void,
   subCount: number,
-  isLivestreamActive: boolean,
 };
 
 // previews used in channel overview and homepage (and other places?)
 function ClaimPreviewSubtitle(props: Props) {
-  const { pending, uri, claim, type, beginPublish, isLivestream, isLivestreamActive, fetchSubCount, subCount } = props;
+  const { pending, uri, claim, type, beginPublish, isLivestream, fetchSubCount, subCount } = props;
   const isChannel = claim && claim.value_type === 'channel';
   const claimsInChannel = (claim && claim.meta.claims_in_channel) || 0;
 
@@ -41,29 +39,6 @@ function ClaimPreviewSubtitle(props: Props) {
     ({ streamName: name } = parseURI(uri));
   } catch (e) {}
 
-  const { listingType } = useContext(ClaimListDiscoverContext) || {};
-
-  const LivestreamDateTimeLabel = () => {
-    // If showing in upcoming and in the past. (we allow x time in past to show here if not live yet)
-    if (listingType === 'UPCOMING') {
-      // $FlowFixMe
-      if (moment.unix(claim.value.release_time).isBefore()) {
-        return __('Starting Soon');
-      }
-    } else {
-      // If not in upcoming + live and in the future (started streaming a bit early)
-      // $FlowFixMe
-      if (isLivestreamActive && moment.unix(claim.value.release_time).isAfter()) {
-        return __('Streaming Now');
-      }
-    }
-    return (
-      <>
-        {__('Livestream')} <DateTime timeAgo uri={uri} />
-      </>
-    );
-  };
-
   return (
     <div className="media__subtitle">
       {claim ? (
@@ -82,7 +57,7 @@ function ClaimPreviewSubtitle(props: Props) {
 
               {!isChannel &&
                 (isLivestream && ENABLE_NO_SOURCE_CLAIMS ? (
-                  <LivestreamDateTimeLabel />
+                  <LivestreamDateTime uri={uri} />
                 ) : (
                   <>
                     <FileViewCountInline uri={uri} isLivestream={isLivestream} />
diff --git a/ui/component/claimPreviewTile/view.jsx b/ui/component/claimPreviewTile/view.jsx
index a89d6449e..5244ba03e 100644
--- a/ui/component/claimPreviewTile/view.jsx
+++ b/ui/component/claimPreviewTile/view.jsx
@@ -1,11 +1,12 @@
 // @flow
-import React, { useContext } from 'react';
+import React from 'react';
 import classnames from 'classnames';
 import { NavLink, withRouter } from 'react-router-dom';
 import FileThumbnail from 'component/fileThumbnail';
 import UriIndicator from 'component/uriIndicator';
 import TruncatedText from 'component/common/truncated-text';
 import DateTime from 'component/dateTime';
+import LivestreamDateTime from 'component/livestreamDateTime';
 import ChannelThumbnail from 'component/channelThumbnail';
 import FileViewCountInline from 'component/fileViewCountInline';
 import SubscribeButton from 'component/subscribeButton';
@@ -19,8 +20,6 @@ import FileWatchLaterLink from 'component/fileWatchLaterLink';
 import ClaimRepostAuthor from 'component/claimRepostAuthor';
 import ClaimMenuList from 'component/claimMenuList';
 import CollectionPreviewOverlay from 'component/collectionPreviewOverlay';
-import ClaimListDiscoverContext from 'component/claimListDiscover/context';
-import moment from 'moment';
 // $FlowFixMe cannot resolve ...
 import PlaceholderTx from 'static/img/placeholderTx.gif';
 
@@ -110,8 +109,6 @@ function ClaimPreviewTile(props: Props) {
     }
   }
 
-  const { listingType } = useContext(ClaimListDiscoverContext) || {};
-
   const signingChannel = claim && claim.signing_channel;
   const isChannel = claim && claim.value_type === 'channel';
   const channelUri = !isChannel ? signingChannel && signingChannel.permanent_url : claim && claim.permanent_url;
@@ -175,23 +172,6 @@ function ClaimPreviewTile(props: Props) {
     liveProperty = (claim) => <>LIVE</>;
   }
 
-  const LivestreamDateTimeLabel = () => {
-    // If showing in upcoming and in the past. (we allow x time in past to show here if not live yet)
-    if (listingType === 'UPCOMING') {
-      // $FlowFixMe
-      if (moment.unix(claim.value.release_time).isBefore()) {
-        return __('Starting Soon');
-      }
-    } else {
-      // If not in upcoming + live and in the future (started streaming a bit early)
-      // $FlowFixMe
-      if (isLivestreamActive && moment.unix(claim.value.release_time).isAfter()) {
-        return __('Streaming Now');
-      }
-    }
-    return <DateTime timeAgo uri={uri} />;
-  };
-
   return (
     <li
       onClick={handleClick}
@@ -260,7 +240,7 @@ function ClaimPreviewTile(props: Props) {
                 <UriIndicator uri={uri} link />
                 <div className="claim-tile__about--counts">
                   <FileViewCountInline uri={uri} isLivestream={isLivestream} />
-                  {isLivestream && <LivestreamDateTimeLabel />}
+                  {isLivestream && <LivestreamDateTime uri={uri} />}
                   {!isLivestream && <DateTime timeAgo uri={uri} />}
                 </div>
               </div>
diff --git a/ui/component/fileSubtitle/view.jsx b/ui/component/fileSubtitle/view.jsx
index 54acdabdc..ab10ac7cd 100644
--- a/ui/component/fileSubtitle/view.jsx
+++ b/ui/component/fileSubtitle/view.jsx
@@ -4,6 +4,7 @@ import DateTime from 'component/dateTime';
 import FileViewCount from 'component/fileViewCount';
 import FileActions from 'component/fileActions';
 import ClaimPreviewReset from 'component/claimPreviewReset';
+import LivestreamDateTime from 'component/livestreamDateTime';
 
 type Props = {
   uri: string,
@@ -13,13 +14,12 @@ type Props = {
 
 function FileSubtitle(props: Props) {
   const { uri, livestream = false, isLive = false } = props;
-  const showDateTime = !livestream || (livestream && !isLive);
   return (
     <>
       <div className="media__subtitle--between">
         <div className="file__viewdate">
-          {showDateTime && <DateTime uri={uri} show={DateTime.SHOW_DATE} />}
-
+          {livestream && isLive && <LivestreamDateTime uri={uri} />}
+          {!livestream && <DateTime uri={uri} show={DateTime.SHOW_DATE} />}
           <FileViewCount uri={uri} livestream={livestream} isLive={isLive} />
         </div>
 
diff --git a/ui/component/livestreamDateTime/index.js b/ui/component/livestreamDateTime/index.js
new file mode 100644
index 000000000..b64475699
--- /dev/null
+++ b/ui/component/livestreamDateTime/index.js
@@ -0,0 +1,14 @@
+import { connect } from 'react-redux';
+import { makeSelectClaimForUri } from 'redux/selectors/claims';
+import LivestreamDateTime from './view';
+import { selectActiveLivestreamForUri } from 'redux/selectors/livestream';
+
+const select = (state, props) => {
+  const claim = props.uri && makeSelectClaimForUri(props.uri)(state);
+  return {
+    claim,
+    activeLivestream: selectActiveLivestreamForUri(state, props.uri),
+  };
+};
+
+export default connect(select)(LivestreamDateTime);
diff --git a/ui/component/livestreamDateTime/view.jsx b/ui/component/livestreamDateTime/view.jsx
new file mode 100644
index 000000000..c06d4071f
--- /dev/null
+++ b/ui/component/livestreamDateTime/view.jsx
@@ -0,0 +1,37 @@
+// @flow
+import React from 'react';
+import DateTime from 'component/dateTime';
+import { LIVESTREAM_STARTED_RECENTLY_BUFFER } from 'constants/livestream';
+import moment from 'moment';
+
+type Props = {
+  uri: string,
+  claim: any,
+  activeLivestream: any,
+};
+
+const LivestreamDateTime = (props: Props) => {
+  const { uri, claim, activeLivestream } = props;
+
+  if (activeLivestream) {
+    return (
+      <span>
+        {__('Started')} <DateTime timeAgo date={activeLivestream.startedStreaming.toDate()} />
+      </span>
+    );
+  }
+  if (
+    moment
+      .unix(claim.value.release_time)
+      .isBetween(moment().subtract(LIVESTREAM_STARTED_RECENTLY_BUFFER, 'minutes'), moment())
+  ) {
+    return __('Starting Soon');
+  }
+  return (
+    <span>
+      {__('Live')} <DateTime timeAgo uri={uri} />
+    </span>
+  );
+};
+
+export default LivestreamDateTime;
diff --git a/ui/component/livestreamLayout/view.jsx b/ui/component/livestreamLayout/view.jsx
index ce8b7dce7..c01719cc6 100644
--- a/ui/component/livestreamLayout/view.jsx
+++ b/ui/component/livestreamLayout/view.jsx
@@ -80,7 +80,12 @@ export default function LivestreamLayout(props: Props) {
           </div>
         )}
 
-        {activeStreamUri && <LivestreamLink claimUri={activeStreamUri} />}
+        {activeStreamUri && (
+          <LivestreamLink
+            title={__("Click here to access the stream that's currently active")}
+            claimUri={activeStreamUri}
+          />
+        )}
 
         <React.Suspense fallback={null}>{isMobile && !hideComments && <LivestreamComments uri={uri} />}</React.Suspense>
 
diff --git a/ui/component/livestreamLink/view.jsx b/ui/component/livestreamLink/view.jsx
index f111112db..75e08a955 100644
--- a/ui/component/livestreamLink/view.jsx
+++ b/ui/component/livestreamLink/view.jsx
@@ -7,17 +7,18 @@ import { useHistory } from 'react-router';
 import { formatLbryUrlForWeb } from 'util/url';
 
 type Props = {
+  title?: string,
   claimUri: string,
 };
 
 export default function LivestreamLink(props: Props) {
-  const { claimUri } = props;
+  const { claimUri, title = null } = props;
   const { push } = useHistory();
 
   const element = (props: { children: any }) => (
     <Card
       className="livestream__channel-link claim-preview__live"
-      title={__('Live stream in progress')}
+      title={title || __('Live stream in progress')}
       onClick={() => {
         push(formatLbryUrlForWeb(claimUri));
       }}
diff --git a/ui/component/scheduledStreams/view.jsx b/ui/component/scheduledStreams/view.jsx
index 88e1f1408..231c7decb 100644
--- a/ui/component/scheduledStreams/view.jsx
+++ b/ui/component/scheduledStreams/view.jsx
@@ -8,7 +8,6 @@ import { useIsMediumScreen, useIsLargeScreen } from 'effects/use-screensize';
 import ClaimListDiscover from 'component/claimListDiscover';
 import Button from 'component/button';
 import { LIVESTREAM_UPCOMING_BUFFER } from 'constants/livestream';
-import ClaimListDiscoverContext from 'component/claimListDiscover/context';
 
 type Props = {
   channelIds: Array<string>,
@@ -39,56 +38,54 @@ const ScheduledStreams = (props: Props) => {
   };
 
   return (
-    <ClaimListDiscoverContext.Provider value={{ listingType: 'UPCOMING' }}>
-      <div className={'mb-xl'} style={{ display: showUpcomingLivestreams ? 'block' : 'none' }}>
-        <ClaimListDiscover
-          useSkeletonScreen={false}
-          channelIds={channelIds}
-          limitClaimsPerChannel={limitClaimsPerChannel}
-          pageSize={50}
-          streamType={'all'}
-          hasNoSource
-          orderBy={CS.ORDER_BY_NEW_ASC}
-          tileLayout={tileLayout}
-          releaseTime={`>${moment().subtract(LIVESTREAM_UPCOMING_BUFFER, 'minutes').startOf('minute').unix()}`}
-          hideAdvancedFilter
-          hideFilters
-          infiniteScroll={false}
-          showNoSourceClaims
-          hideLayoutButton
-          header={__('Upcoming Livestreams')}
-          maxClaimRender={upcomingMax}
-          excludeUris={liveUris}
-          loadedCallback={loadedCallback}
-        />
-        {totalUpcomingLivestreams > upcomingMax && !showAllUpcoming && (
-          <div className="livestream-list--view-more">
-            <Button
-              label={__('Show more upcoming livestreams')}
-              button="link"
-              iconRight={ICONS.ARROW_RIGHT}
-              className="claim-grid__title--secondary"
-              onClick={() => {
-                setShowAllUpcoming(true);
-              }}
-            />
-          </div>
-        )}
-        {showAllUpcoming && (
-          <div className="livestream-list--view-more">
-            <Button
-              label={__('Show less upcoming livestreams')}
-              button="link"
-              iconRight={ICONS.ARROW_RIGHT}
-              className="claim-grid__title--secondary"
-              onClick={() => {
-                setShowAllUpcoming(false);
-              }}
-            />
-          </div>
-        )}
-      </div>
-    </ClaimListDiscoverContext.Provider>
+    <div className={'mb-xl'} style={{ display: showUpcomingLivestreams ? 'block' : 'none' }}>
+      <ClaimListDiscover
+        useSkeletonScreen={false}
+        channelIds={channelIds}
+        limitClaimsPerChannel={limitClaimsPerChannel}
+        pageSize={50}
+        streamType={'all'}
+        hasNoSource
+        orderBy={CS.ORDER_BY_NEW_ASC}
+        tileLayout={tileLayout}
+        releaseTime={`>${moment().subtract(LIVESTREAM_UPCOMING_BUFFER, 'minutes').startOf('minute').unix()}`}
+        hideAdvancedFilter
+        hideFilters
+        infiniteScroll={false}
+        showNoSourceClaims
+        hideLayoutButton
+        header={__('Upcoming Livestreams')}
+        maxClaimRender={upcomingMax}
+        excludeUris={liveUris}
+        loadedCallback={loadedCallback}
+      />
+      {totalUpcomingLivestreams > upcomingMax && !showAllUpcoming && (
+        <div className="livestream-list--view-more">
+          <Button
+            label={__('Show more upcoming livestreams')}
+            button="link"
+            iconRight={ICONS.ARROW_RIGHT}
+            className="claim-grid__title--secondary"
+            onClick={() => {
+              setShowAllUpcoming(true);
+            }}
+          />
+        </div>
+      )}
+      {showAllUpcoming && (
+        <div className="livestream-list--view-more">
+          <Button
+            label={__('Show less upcoming livestreams')}
+            button="link"
+            iconRight={ICONS.ARROW_RIGHT}
+            className="claim-grid__title--secondary"
+            onClick={() => {
+              setShowAllUpcoming(false);
+            }}
+          />
+        </div>
+      )}
+    </div>
   );
 };
 
diff --git a/ui/page/livestream/index.js b/ui/page/livestream/index.js
index dd6dcc70a..5d3ce19b8 100644
--- a/ui/page/livestream/index.js
+++ b/ui/page/livestream/index.js
@@ -6,16 +6,20 @@ import { selectUserVerifiedEmail } from 'redux/selectors/user';
 import { DISABLE_COMMENTS_TAG } from 'constants/tags';
 import { doCommentSocketConnect, doCommentSocketDisconnect } from 'redux/actions/websocket';
 import { getChannelIdFromClaim } from 'util/claim';
-import { selectCurrentChannelStatus } from 'redux/selectors/livestream';
+import { selectActiveLivestreamForChannel, selectActiveLivestreamInitialized } from 'redux/selectors/livestream';
 import { doFetchActiveLivestream } from 'redux/actions/livestream';
 import LivestreamPage from './view';
 
-const select = (state, props) => ({
-  isAuthenticated: selectUserVerifiedEmail(state),
-  channelClaimId: getChannelIdFromClaim(selectClaimForUri(state, props.uri)),
-  chatDisabled: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_COMMENTS_TAG)(state),
-  currentChannelStatus: selectCurrentChannelStatus(state),
-});
+const select = (state, props) => {
+  const channelClaimId = getChannelIdFromClaim(selectClaimForUri(state, props.uri));
+  return {
+    isAuthenticated: selectUserVerifiedEmail(state),
+    channelClaimId,
+    chatDisabled: makeSelectTagInClaimOrChannelForUri(props.uri, DISABLE_COMMENTS_TAG)(state),
+    activeLivestreamForChannel: selectActiveLivestreamForChannel(state, channelClaimId),
+    activeLivestreamInitialized: selectActiveLivestreamInitialized(state),
+  };
+};
 
 const perform = {
   doSetPlayingUri,
diff --git a/ui/page/livestream/view.jsx b/ui/page/livestream/view.jsx
index 3c19fd7d3..ca5fc204d 100644
--- a/ui/page/livestream/view.jsx
+++ b/ui/page/livestream/view.jsx
@@ -20,7 +20,8 @@ type Props = {
   doCommentSocketConnect: (string, string) => void,
   doCommentSocketDisconnect: (string) => void,
   doFetchActiveLivestream: (string) => void,
-  currentChannelStatus: LivestreamChannelStatus,
+  activeLivestreamForChannel: any,
+  activeLivestreamInitialized: boolean,
 };
 
 export default function LivestreamPage(props: Props) {
@@ -35,7 +36,8 @@ export default function LivestreamPage(props: Props) {
     doCommentSocketConnect,
     doCommentSocketDisconnect,
     doFetchActiveLivestream,
-    currentChannelStatus,
+    activeLivestreamForChannel,
+    activeLivestreamInitialized,
   } = props;
 
   React.useEffect(() => {
@@ -58,10 +60,9 @@ export default function LivestreamPage(props: Props) {
     };
   }, [claimId, uri, doCommentSocketConnect, doCommentSocketDisconnect]);
 
-  const [isInitialized, setIsInitialized] = React.useState(false);
-  const [isChannelBroadcasting, setIsChannelBroadcasting] = React.useState(false);
-  const [isCurrentClaimLive, setIsCurrentClaimLive] = React.useState(false);
-
+  const isInitialized = Boolean(activeLivestreamForChannel) || activeLivestreamInitialized;
+  const isChannelBroadcasting = Boolean(activeLivestreamForChannel);
+  const isCurrentClaimLive = isChannelBroadcasting && activeLivestreamForChannel.claimId === claimId;
   const livestreamChannelId = channelClaimId || '';
 
   // Find out current channels status + active live claim.
@@ -71,19 +72,10 @@ export default function LivestreamPage(props: Props) {
     return () => clearInterval(intervalId);
   }, [livestreamChannelId, doFetchActiveLivestream]);
 
-  React.useEffect(() => {
-    const initialized = currentChannelStatus.channelId === livestreamChannelId;
-    setIsInitialized(initialized);
-    if (initialized) {
-      setIsChannelBroadcasting(currentChannelStatus.isBroadcasting);
-      setIsCurrentClaimLive(currentChannelStatus.liveClaim.claimId === claimId);
-    }
-  }, [currentChannelStatus, livestreamChannelId, claimId]);
-
   const [activeStreamUri, setActiveStreamUri] = React.useState(false);
 
   React.useEffect(() => {
-    setActiveStreamUri(!isCurrentClaimLive && isChannelBroadcasting ? currentChannelStatus.liveClaim.claimUri : false);
+    setActiveStreamUri(!isCurrentClaimLive && isChannelBroadcasting ? activeLivestreamForChannel.claimUri : false);
   }, [isCurrentClaimLive, isChannelBroadcasting]); // eslint-disable-line react-hooks/exhaustive-deps
 
   // $FlowFixMe
diff --git a/ui/redux/actions/livestream.js b/ui/redux/actions/livestream.js
index 7338a313b..7c43bf220 100644
--- a/ui/redux/actions/livestream.js
+++ b/ui/redux/actions/livestream.js
@@ -165,14 +165,18 @@ export const doFetchActiveLivestream = (channelId: string) => {
       const liveChannel = await fetchLiveChannel(channelId);
       const currentlyLiveClaims = await findActiveStreams([channelId], ['release_time'], liveChannel, dispatch);
       const liveClaim = currentlyLiveClaims[channelId];
+
+      liveChannel[channelId].claimId = liveClaim.stream.claim_id;
+      liveChannel[channelId].claimUri = liveClaim.stream.canonical_url;
+
       dispatch({
         type: ACTIONS.FETCH_ACTIVE_LIVESTREAM_COMPLETED,
-        data: { liveClaim: { claimId: liveClaim.stream.claim_id, claimUri: liveClaim.stream.canonical_url } },
+        data: {
+          ...liveChannel,
+        },
       });
     } catch (err) {
-      dispatch({ type: ACTIONS.FETCH_ACTIVE_LIVESTREAM_FAILED });
-    } finally {
-      dispatch({ type: ACTIONS.FETCH_ACTIVE_LIVESTREAM_FINISHED, data: { channelId } });
+      dispatch({ type: ACTIONS.FETCH_ACTIVE_LIVESTREAM_FAILED, data: { channelId } });
     }
   };
 };
diff --git a/ui/redux/reducers/livestream.js b/ui/redux/reducers/livestream.js
index 6ffeecc91..ebd78b476 100644
--- a/ui/redux/reducers/livestream.js
+++ b/ui/redux/reducers/livestream.js
@@ -3,15 +3,6 @@
 import * as ACTIONS from 'constants/action_types';
 import { handleActions } from 'util/redux-utils';
 
-const currentChannelStatus: LivestreamChannelStatus = {
-  channelId: null,
-  isBroadcasting: false,
-  liveClaim: {
-    claimId: null,
-    claimUri: null,
-  },
-};
-
 const defaultState: LivestreamState = {
   fetchingById: {},
   viewersById: {},
@@ -19,10 +10,7 @@ const defaultState: LivestreamState = {
   activeLivestreams: null,
   activeLivestreamsLastFetchedDate: 0,
   activeLivestreamsLastFetchedOptions: {},
-
-  currentChannelStatus: {
-    ...currentChannelStatus,
-  },
+  activeLivestreamInitialized: false,
 };
 
 export default handleActions(
@@ -70,24 +58,14 @@ export default handleActions(
         activeLivestreamsLastFetchedOptions,
       };
     },
-
     [ACTIONS.FETCH_ACTIVE_LIVESTREAM_COMPLETED]: (state: LivestreamState, action: any) => {
-      const currentChannelStatus = Object.assign({}, state.currentChannelStatus, {
-        isBroadcasting: true,
-        liveClaim: action.data.liveClaim,
-      });
-      return { ...state, currentChannelStatus };
+      const activeLivestreams = Object.assign({}, state.activeLivestreams || {}, action.data);
+      return { ...state, activeLivestreams, activeLivestreamInitialized: true };
     },
-    [ACTIONS.FETCH_ACTIVE_LIVESTREAM_FAILED]: (state: LivestreamState) => {
-      const currentChannelStatus = Object.assign({}, state.currentChannelStatus, {
-        isBroadcasting: false,
-        liveClaim: { claimId: null, claimUri: null },
-      });
-      return { ...state, currentChannelStatus };
-    },
-    [ACTIONS.FETCH_ACTIVE_LIVESTREAM_FINISHED]: (state: LivestreamState, action: any) => {
-      const currentChannelStatus = Object.assign({}, state.currentChannelStatus, { channelId: action.data.channelId });
-      return { ...state, currentChannelStatus };
+    [ACTIONS.FETCH_ACTIVE_LIVESTREAM_FAILED]: (state: LivestreamState, action: any) => {
+      const activeLivestreams = state.activeLivestreams;
+      if (activeLivestreams) delete activeLivestreams[action.data.channelId];
+      return { ...state, activeLivestreams: Object.assign({}, activeLivestreams), activeLivestreamInitialized: true };
     },
   },
   defaultState
diff --git a/ui/redux/selectors/livestream.js b/ui/redux/selectors/livestream.js
index e22775c97..f8774134b 100644
--- a/ui/redux/selectors/livestream.js
+++ b/ui/redux/selectors/livestream.js
@@ -62,6 +62,31 @@ export const selectIsActiveLivestreamForUri = createCachedSelector(
   }
 )((state, uri) => String(uri));
 
+export const selectActiveLivestreamForUri = createCachedSelector(
+  (state, uri) => uri,
+  selectActiveLivestreams,
+  (uri, activeLivestreams) => {
+    if (!uri || !activeLivestreams) {
+      return null;
+    }
+
+    const activeLivestreamValues = Object.values(activeLivestreams);
+    // $FlowFixMe - unable to resolve claimUri
+    return activeLivestreamValues.find((v) => v.claimUri === uri) || null;
+  }
+)((state, uri) => String(uri));
+
+export const selectActiveLivestreamForChannel = createCachedSelector(
+  (state, channelId) => channelId,
+  selectActiveLivestreams,
+  (channelId, activeLivestreams) => {
+    if (!channelId || !activeLivestreams) {
+      return null;
+    }
+    return activeLivestreams[channelId] || null;
+  }
+)((state, channelId) => String(channelId));
+
 export const selectFetchingActiveLivestreams = (state: State) => selectState(state).fetchingActiveLivestreams;
 
-export const selectCurrentChannelStatus = (state: State) => selectState(state).currentChannelStatus;
+export const selectActiveLivestreamInitialized = (state: State) => selectState(state).activeLivestreamInitialized;