2021-03-02 03:07:10 +01:00
|
|
|
// @flow
|
|
|
|
import React from 'react';
|
2021-10-18 17:54:59 +02:00
|
|
|
import { lazyImport } from 'util/lazyImport';
|
2021-03-02 03:07:10 +01:00
|
|
|
import Page from 'component/page';
|
2021-03-15 15:32:51 +01:00
|
|
|
import LivestreamLayout from 'component/livestreamLayout';
|
|
|
|
import analytics from 'analytics';
|
2021-10-17 10:36:14 +02:00
|
|
|
import Lbry from 'lbry';
|
2021-11-05 20:14:00 +01:00
|
|
|
import watchLivestreamStatus from '$web/src/livestreaming/long-polling';
|
2021-03-02 03:07:10 +01:00
|
|
|
|
2021-10-18 17:54:59 +02:00
|
|
|
const LivestreamComments = lazyImport(() => import('component/livestreamComments' /* webpackChunkName: "comments" */));
|
|
|
|
|
2021-03-02 03:07:10 +01:00
|
|
|
type Props = {
|
2021-03-15 15:32:51 +01:00
|
|
|
uri: string,
|
|
|
|
claim: StreamClaim,
|
|
|
|
doSetPlayingUri: ({ uri: ?string }) => void,
|
|
|
|
isAuthenticated: boolean,
|
|
|
|
doUserSetReferrer: (string) => void,
|
2021-03-22 10:42:02 +01:00
|
|
|
channelClaim: ChannelClaim,
|
2021-06-03 17:55:16 +02:00
|
|
|
chatDisabled: boolean,
|
2021-03-02 03:07:10 +01:00
|
|
|
};
|
|
|
|
|
2021-03-15 15:32:51 +01:00
|
|
|
export default function LivestreamPage(props: Props) {
|
2021-06-03 17:55:16 +02:00
|
|
|
const { uri, claim, doSetPlayingUri, isAuthenticated, doUserSetReferrer, channelClaim, chatDisabled } = props;
|
2021-11-10 20:15:40 +01:00
|
|
|
const [isLive, setIsLive] = React.useState(true);
|
2021-03-22 10:42:02 +01:00
|
|
|
const livestreamChannelId = channelClaim && channelClaim.signing_channel && channelClaim.signing_channel.claim_id;
|
2021-03-30 01:05:18 +02:00
|
|
|
const [hasLivestreamClaim, setHasLivestreamClaim] = React.useState(false);
|
2021-03-02 03:07:10 +01:00
|
|
|
|
2021-03-30 01:05:18 +02:00
|
|
|
const LIVESTREAM_CLAIM_POLL_IN_MS = 60000;
|
|
|
|
|
2021-03-15 15:32:51 +01:00
|
|
|
React.useEffect(() => {
|
2021-03-30 01:05:18 +02:00
|
|
|
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(() => {
|
2021-11-15 17:52:00 +01:00
|
|
|
if (!hasLivestreamClaim || !livestreamChannelId) return;
|
2021-11-05 20:14:00 +01:00
|
|
|
return watchLivestreamStatus(livestreamChannelId, (state) => setIsLive(state));
|
|
|
|
}, [livestreamChannelId, setIsLive, hasLivestreamClaim]);
|
2021-03-15 15:32:51 +01:00
|
|
|
|
|
|
|
const stringifiedClaim = JSON.stringify(claim);
|
|
|
|
React.useEffect(() => {
|
|
|
|
if (uri && stringifiedClaim) {
|
|
|
|
const jsonClaim = JSON.parse(stringifiedClaim);
|
2021-03-02 03:07:10 +01:00
|
|
|
|
2021-03-15 15:32:51 +01:00
|
|
|
if (jsonClaim) {
|
|
|
|
const { txid, nout, claim_id: claimId } = jsonClaim;
|
|
|
|
const outpoint = `${txid}:${nout}`;
|
2021-03-02 03:07:10 +01:00
|
|
|
|
2021-03-15 15:32:51 +01:00
|
|
|
analytics.apiLogView(uri, outpoint, claimId);
|
|
|
|
}
|
2021-03-02 03:07:10 +01:00
|
|
|
|
2021-03-15 15:32:51 +01:00
|
|
|
if (!isAuthenticated) {
|
|
|
|
const uri = jsonClaim.signing_channel && jsonClaim.signing_channel.permanent_url;
|
|
|
|
if (uri) {
|
|
|
|
doUserSetReferrer(uri.replace('lbry://', ''));
|
|
|
|
}
|
2021-03-02 03:07:10 +01:00
|
|
|
}
|
|
|
|
}
|
2021-03-15 15:32:51 +01:00
|
|
|
}, [uri, stringifiedClaim, isAuthenticated]);
|
2021-03-02 03:07:10 +01:00
|
|
|
|
|
|
|
React.useEffect(() => {
|
2021-03-15 15:32:51 +01:00
|
|
|
// Set playing uri to null so the popout player doesnt start playing the dummy claim if a user navigates back
|
2021-07-27 22:35:22 +02:00
|
|
|
// This can be removed when we start using the app video player, not a LIVESTREAM iframe
|
2021-03-15 15:32:51 +01:00
|
|
|
doSetPlayingUri({ uri: null });
|
|
|
|
}, [doSetPlayingUri]);
|
2021-03-02 03:07:10 +01:00
|
|
|
|
|
|
|
return (
|
2021-06-03 17:55:16 +02:00
|
|
|
<Page
|
|
|
|
className="file-page"
|
|
|
|
noFooter
|
|
|
|
livestream
|
|
|
|
chatDisabled={chatDisabled}
|
2021-10-18 17:54:59 +02:00
|
|
|
rightSide={
|
|
|
|
!chatDisabled && (
|
|
|
|
<React.Suspense fallback={null}>
|
|
|
|
<LivestreamComments uri={uri} />
|
|
|
|
</React.Suspense>
|
|
|
|
)
|
|
|
|
}
|
2021-06-03 17:55:16 +02:00
|
|
|
>
|
2021-06-17 20:55:23 +02:00
|
|
|
<LivestreamLayout uri={uri} isLive={isLive} />
|
2021-03-02 03:07:10 +01:00
|
|
|
</Page>
|
|
|
|
);
|
|
|
|
}
|