f092e8cb7b
channelContent - live only poll streaming if has livestream claim check channel for livestream claims every minute update consts poll livestream claims on setup page do not poll livestream claims if live smoother loading unmerged redux bump
119 lines
3.7 KiB
JavaScript
119 lines
3.7 KiB
JavaScript
// @flow
|
|
import { BITWAVE_API } from 'constants/livestream';
|
|
import React from 'react';
|
|
import Page from 'component/page';
|
|
import LivestreamLayout from 'component/livestreamLayout';
|
|
import analytics from 'analytics';
|
|
import { Lbry } from 'lbry-redux';
|
|
|
|
type Props = {
|
|
uri: string,
|
|
claim: StreamClaim,
|
|
doSetPlayingUri: ({ uri: ?string }) => void,
|
|
isAuthenticated: boolean,
|
|
doUserSetReferrer: (string) => void,
|
|
channelClaim: ChannelClaim,
|
|
};
|
|
|
|
export default function LivestreamPage(props: Props) {
|
|
const { uri, claim, doSetPlayingUri, isAuthenticated, doUserSetReferrer, channelClaim } = props;
|
|
const [activeViewers, setActiveViewers] = React.useState(0);
|
|
const [isLive, setIsLive] = React.useState(false);
|
|
const livestreamChannelId = channelClaim && channelClaim.signing_channel && channelClaim.signing_channel.claim_id;
|
|
const [hasLivestreamClaim, setHasLivestreamClaim] = React.useState(false);
|
|
|
|
const STREAMING_POLL_INTERVAL_IN_MS = 10000;
|
|
const LIVESTREAM_CLAIM_POLL_IN_MS = 60000;
|
|
|
|
// the component needs to check if the channel has published a new livestream, so we know if it should check
|
|
React.useEffect(() => {
|
|
let checkClaimsInterval;
|
|
function checkHasLivestreamClaim() {
|
|
Lbry.claim_search({
|
|
channel_ids: [livestreamChannelId],
|
|
has_no_source: true,
|
|
claim_type: ['stream'],
|
|
})
|
|
.then((res) => {
|
|
if (res && res.items && res.items.length > 0) {
|
|
setHasLivestreamClaim(true);
|
|
}
|
|
})
|
|
.catch(() => {});
|
|
}
|
|
if (livestreamChannelId && !isLive) {
|
|
if (!checkClaimsInterval) checkHasLivestreamClaim();
|
|
checkClaimsInterval = setInterval(checkHasLivestreamClaim, LIVESTREAM_CLAIM_POLL_IN_MS);
|
|
|
|
return () => {
|
|
if (checkClaimsInterval) {
|
|
clearInterval(checkClaimsInterval);
|
|
}
|
|
};
|
|
}
|
|
}, [livestreamChannelId, isLive]);
|
|
|
|
React.useEffect(() => {
|
|
let interval;
|
|
function checkIsLive() {
|
|
// $FlowFixMe Bitwave's API can handle garbage
|
|
fetch(`${BITWAVE_API}/${livestreamChannelId}`)
|
|
.then((res) => res.json())
|
|
.then((res) => {
|
|
if (!res || !res.data) {
|
|
setIsLive(false);
|
|
return;
|
|
}
|
|
|
|
setActiveViewers(res.data.viewCount);
|
|
|
|
if (res.data.hasOwnProperty('live')) {
|
|
setIsLive(res.data.live);
|
|
}
|
|
});
|
|
}
|
|
if (livestreamChannelId && hasLivestreamClaim) {
|
|
if (!interval) checkIsLive();
|
|
interval = setInterval(checkIsLive, STREAMING_POLL_INTERVAL_IN_MS);
|
|
|
|
return () => {
|
|
if (interval) {
|
|
clearInterval(interval);
|
|
}
|
|
};
|
|
}
|
|
}, [livestreamChannelId, hasLivestreamClaim]);
|
|
|
|
const stringifiedClaim = JSON.stringify(claim);
|
|
React.useEffect(() => {
|
|
if (uri && stringifiedClaim) {
|
|
const jsonClaim = JSON.parse(stringifiedClaim);
|
|
|
|
if (jsonClaim) {
|
|
const { txid, nout, claim_id: claimId } = jsonClaim;
|
|
const outpoint = `${txid}:${nout}`;
|
|
|
|
analytics.apiLogView(uri, outpoint, claimId);
|
|
}
|
|
|
|
if (!isAuthenticated) {
|
|
const uri = jsonClaim.signing_channel && jsonClaim.signing_channel.permanent_url;
|
|
if (uri) {
|
|
doUserSetReferrer(uri.replace('lbry://', ''));
|
|
}
|
|
}
|
|
}
|
|
}, [uri, stringifiedClaim, isAuthenticated]);
|
|
|
|
React.useEffect(() => {
|
|
// Set playing uri to null so the popout player doesnt start playing the dummy claim if a user navigates back
|
|
// This can be removed when we start using the app video player, not a bitwave iframe
|
|
doSetPlayingUri({ uri: null });
|
|
}, [doSetPlayingUri]);
|
|
|
|
return (
|
|
<Page className="file-page" filePage livestream>
|
|
<LivestreamLayout uri={uri} activeViewers={activeViewers} isLive={isLive} />
|
|
</Page>
|
|
);
|
|
}
|