use commentron for live view counts

This commit is contained in:
zeppi 2021-06-17 14:55:23 -04:00 committed by jessopb
parent eb0992879c
commit 03e921e6df
10 changed files with 46 additions and 23 deletions

View file

@ -23,4 +23,5 @@ declare type LivestreamReplayData = Array<LivestreamReplayItem>;
declare type LivestreamState = { declare type LivestreamState = {
fetchingById: {}, fetchingById: {},
viewersById: {},
} }

View file

@ -1,11 +1,17 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { makeSelectTitleForUri } from 'lbry-redux'; import { makeSelectTitleForUri, makeSelectClaimForUri } from 'lbry-redux';
import { makeSelectInsufficientCreditsForUri } from 'redux/selectors/content'; import { makeSelectInsufficientCreditsForUri } from 'redux/selectors/content';
import { makeSelectViewersForId } from 'redux/selectors/livestream';
import FileTitleSection from './view'; import FileTitleSection from './view';
const select = (state, props) => ({ const select = (state, props) => {
isInsufficientCredits: makeSelectInsufficientCreditsForUri(props.uri)(state), const claim = makeSelectClaimForUri(props.uri)(state);
title: makeSelectTitleForUri(props.uri)(state), const viewers = claim && makeSelectViewersForId(claim.claim_id)(state);
}); return {
viewers,
isInsufficientCredits: makeSelectInsufficientCreditsForUri(props.uri)(state),
title: makeSelectTitleForUri(props.uri)(state),
};
};
export default connect(select)(FileTitleSection); export default connect(select)(FileTitleSection);

View file

@ -21,11 +21,11 @@ type Props = {
isNsfwBlocked: boolean, isNsfwBlocked: boolean,
livestream?: boolean, livestream?: boolean,
isLive?: boolean, isLive?: boolean,
activeViewers?: number, viewers?: number,
}; };
function FileTitleSection(props: Props) { function FileTitleSection(props: Props) {
const { title, uri, nsfw, isNsfwBlocked, livestream = false, isLive = false, activeViewers } = props; const { title, uri, nsfw, isNsfwBlocked, livestream = false, isLive = false, viewers } = props;
const [hasAcknowledgedSec, setHasAcknowledgedSec] = usePersistedState('sec-nag', false); const [hasAcknowledgedSec, setHasAcknowledgedSec] = usePersistedState('sec-nag', false);
return ( return (
@ -57,7 +57,7 @@ function FileTitleSection(props: Props) {
body={ body={
<React.Fragment> <React.Fragment>
<ClaimInsufficientCredits uri={uri} /> <ClaimInsufficientCredits uri={uri} />
<FileSubtitle uri={uri} isLive={isLive} livestream={livestream} activeViewers={activeViewers} /> <FileSubtitle uri={uri} isLive={isLive} livestream={livestream} activeViewers={viewers} />
</React.Fragment> </React.Fragment>
} }
actions={ actions={

View file

@ -6,6 +6,7 @@ import HelpLink from 'component/common/help-link';
type Props = { type Props = {
claim: ?StreamClaim, claim: ?StreamClaim,
fetchViewCount: (string) => void, fetchViewCount: (string) => void,
fetchingViewCount: boolean,
uri: string, uri: string,
viewCount: string, viewCount: string,
livestream?: boolean, livestream?: boolean,
@ -36,14 +37,14 @@ function FileViewCount(props: Props) {
return ( return (
<span className="media__subtitle--centered"> <span className="media__subtitle--centered">
{activeViewers !== undefined {isLive &&
? __('%viewer_count% currently %viewer_state%', { __('%viewer_count% currently %viewer_state%', {
viewer_count: activeViewers, viewer_count: activeViewers === undefined ? '...' : activeViewers,
viewer_state: isLive ? __('watching') : __('waiting'), viewer_state: isLive ? __('watching') : __('waiting'),
}) })}
: viewCount !== 1 {!isLive &&
? __('%view_count% views', { view_count: formattedViewCount }) activeViewers === undefined &&
: __('1 view')} (viewCount !== 1 ? __('%view_count% views', { view_count: formattedViewCount }) : __('1 view'))}
{!SIMPLE_SITE && <HelpLink href="https://lbry.com/faq/views" />} {!SIMPLE_SITE && <HelpLink href="https://lbry.com/faq/views" />}
</span> </span>
); );

View file

@ -9,12 +9,11 @@ type Props = {
uri: string, uri: string,
claim: ?StreamClaim, claim: ?StreamClaim,
isLive: boolean, isLive: boolean,
activeViewers: number,
chatDisabled: boolean, chatDisabled: boolean,
}; };
export default function LivestreamLayout(props: Props) { export default function LivestreamLayout(props: Props) {
const { claim, uri, isLive, activeViewers, chatDisabled } = props; const { claim, uri, isLive, chatDisabled } = props;
const isMobile = useIsMobile(); const isMobile = useIsMobile();
if (!claim || !claim.signing_channel) { if (!claim || !claim.signing_channel) {
@ -55,7 +54,7 @@ export default function LivestreamLayout(props: Props) {
{isMobile && <LivestreamComments uri={uri} />} {isMobile && <LivestreamComments uri={uri} />}
<FileTitleSection uri={uri} livestream isLive={isLive} activeViewers={activeViewers} /> <FileTitleSection uri={uri} livestream isLive={isLive} />
</div> </div>
</> </>
); );

View file

@ -339,3 +339,4 @@ export const REPORT_CONTENT_FAILED = 'REPORT_CONTENT_FAILED';
export const FETCH_NO_SOURCE_CLAIMS_STARTED = 'FETCH_NO_SOURCE_CLAIMS_STARTED'; export const FETCH_NO_SOURCE_CLAIMS_STARTED = 'FETCH_NO_SOURCE_CLAIMS_STARTED';
export const FETCH_NO_SOURCE_CLAIMS_COMPLETED = 'FETCH_NO_SOURCE_CLAIMS_COMPLETED'; export const FETCH_NO_SOURCE_CLAIMS_COMPLETED = 'FETCH_NO_SOURCE_CLAIMS_COMPLETED';
export const FETCH_NO_SOURCE_CLAIMS_FAILED = 'FETCH_NO_SOURCE_CLAIMS_FAILED'; export const FETCH_NO_SOURCE_CLAIMS_FAILED = 'FETCH_NO_SOURCE_CLAIMS_FAILED';
export const VIEWERS_RECEIVED = 'VIEWERS_RECEIVED';

View file

@ -19,7 +19,6 @@ type Props = {
export default function LivestreamPage(props: Props) { export default function LivestreamPage(props: Props) {
const { uri, claim, doSetPlayingUri, isAuthenticated, doUserSetReferrer, channelClaim, chatDisabled } = props; const { uri, claim, doSetPlayingUri, isAuthenticated, doUserSetReferrer, channelClaim, chatDisabled } = props;
const [activeViewers, setActiveViewers] = React.useState(0);
const [isLive, setIsLive] = React.useState(false); const [isLive, setIsLive] = React.useState(false);
const livestreamChannelId = channelClaim && channelClaim.signing_channel && channelClaim.signing_channel.claim_id; const livestreamChannelId = channelClaim && channelClaim.signing_channel && channelClaim.signing_channel.claim_id;
const [hasLivestreamClaim, setHasLivestreamClaim] = React.useState(false); const [hasLivestreamClaim, setHasLivestreamClaim] = React.useState(false);
@ -66,8 +65,6 @@ export default function LivestreamPage(props: Props) {
return; return;
} }
setActiveViewers(res.data.viewCount);
if (res.data.hasOwnProperty('live')) { if (res.data.hasOwnProperty('live')) {
setIsLive(res.data.live); setIsLive(res.data.live);
} }
@ -120,7 +117,7 @@ export default function LivestreamPage(props: Props) {
chatDisabled={chatDisabled} chatDisabled={chatDisabled}
rightSide={!chatDisabled && <LivestreamComments uri={uri} />} rightSide={!chatDisabled && <LivestreamComments uri={uri} />}
> >
<LivestreamLayout uri={uri} activeViewers={activeViewers} isLive={isLive} /> <LivestreamLayout uri={uri} isLive={isLive} />
</Page> </Page>
); );
} }

View file

@ -102,6 +102,13 @@ export const doCommentSocketConnect = (uri, claimId) => (dispatch) => {
data: { comment: newComment, claimId, uri }, data: { comment: newComment, claimId, uri },
}); });
} }
if (response.type === 'viewers') {
const connected = response.data.connected;
dispatch({
type: ACTIONS.VIEWERS_RECEIVED,
data: { connected, claimId },
});
}
}); });
}; };

View file

@ -4,6 +4,7 @@ import { handleActions } from 'util/redux-utils';
const defaultState: LivestreamState = { const defaultState: LivestreamState = {
fetchingById: {}, fetchingById: {},
viewersById: {},
}; };
export default handleActions( export default handleActions(
@ -29,6 +30,12 @@ export default handleActions(
return { ...state, fetchingById: newIdsFetching }; return { ...state, fetchingById: newIdsFetching };
}, },
[ACTIONS.VIEWERS_RECEIVED]: (state: LivestreamState, action: any) => {
const { connected, claimId } = action.data;
const newViewersById = Object.assign({}, state.viewersById);
newViewersById[claimId] = connected;
return { ...state, viewersById: newViewersById };
},
}, },
defaultState defaultState
); );

View file

@ -21,10 +21,14 @@ export const makeSelectLivestreamsForChannelId = (channelId: string) =>
}); });
export const selectFetchingLivestreams = createSelector(selectState, (state) => state.fetchingById); export const selectFetchingLivestreams = createSelector(selectState, (state) => state.fetchingById);
export const selectViewersById = createSelector(selectState, (state) => state.viewersById);
export const makeSelectIsFetchingLivestreams = (channelId: string) => export const makeSelectIsFetchingLivestreams = (channelId: string) =>
createSelector(selectFetchingLivestreams, (fetchingLivestreams) => Boolean(fetchingLivestreams[channelId])); createSelector(selectFetchingLivestreams, (fetchingLivestreams) => Boolean(fetchingLivestreams[channelId]));
export const makeSelectViewersForId = (channelId: string) =>
createSelector(selectViewersById, (viewers) => viewers[channelId]);
export const makeSelectPendingLivestreamsForChannelId = (channelId: string) => export const makeSelectPendingLivestreamsForChannelId = (channelId: string) =>
createSelector(selectPendingClaims, (pendingClaims) => { createSelector(selectPendingClaims, (pendingClaims) => {
return pendingClaims.filter( return pendingClaims.filter(