rename livestream + livestreamsetup pages
This commit is contained in:
parent
17d0d9f1e0
commit
372c6d0d9f
6 changed files with 341 additions and 361 deletions
|
@ -1,13 +1,18 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { selectMyChannelClaims, selectFetchingMyChannels } from 'lbry-redux';
|
||||
import { selectActiveChannelClaim } from 'redux/selectors/app';
|
||||
import { doSetActiveChannel } from 'redux/actions/app';
|
||||
import CreatorDashboardPage from './view';
|
||||
import { doResolveUri } from 'lbry-redux';
|
||||
import { doSetPlayingUri } from 'redux/actions/content';
|
||||
import { doUserSetReferrer } from 'redux/actions/user';
|
||||
import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
||||
import { selectHasUnclaimedRefereeReward } from 'redux/selectors/rewards';
|
||||
import LivestreamPage from './view';
|
||||
|
||||
const select = (state) => ({
|
||||
channels: selectMyChannelClaims(state),
|
||||
fetchingChannels: selectFetchingMyChannels(state),
|
||||
activeChannelClaim: selectActiveChannelClaim(state),
|
||||
hasUnclaimedRefereeReward: selectHasUnclaimedRefereeReward(state),
|
||||
isAuthenticated: selectUserVerifiedEmail(state),
|
||||
});
|
||||
|
||||
export default connect(select, { doSetActiveChannel })(CreatorDashboardPage);
|
||||
export default connect(select, {
|
||||
doSetPlayingUri,
|
||||
doResolveUri,
|
||||
doUserSetReferrer,
|
||||
})(LivestreamPage);
|
||||
|
|
|
@ -1,240 +1,114 @@
|
|||
// @flow
|
||||
import * as PAGES from 'constants/pages';
|
||||
// import { LIVE_STREAM_TAG, BITWAVE_API } from 'constants/livestream';
|
||||
import React from 'react';
|
||||
import Page from 'component/page';
|
||||
import Spinner from 'component/spinner';
|
||||
import Button from 'component/button';
|
||||
import ChannelSelector from 'component/channelSelector';
|
||||
import Yrbl from 'component/yrbl';
|
||||
import { Lbry } from 'lbry-redux';
|
||||
import { toHex } from '../../util/hex';
|
||||
import ClaimPreview from '../../component/claimPreview';
|
||||
import { FormField } from '../../component/common/form';
|
||||
import * as PUBLISH_MODES from '../../constants/publish_types';
|
||||
import LivestreamLayout from 'component/livestreamLayout';
|
||||
import analytics from 'analytics';
|
||||
|
||||
type Props = {
|
||||
channels: Array<ChannelClaim>,
|
||||
fetchingChannels: boolean,
|
||||
activeChannelClaim: ?ChannelClaim,
|
||||
uri: string,
|
||||
claim: StreamClaim,
|
||||
doSetPlayingUri: ({ uri: ?string }) => void,
|
||||
isAuthenticated: boolean,
|
||||
doUserSetReferrer: (string) => void,
|
||||
};
|
||||
|
||||
export default function CreatorDashboardPage(props: Props) {
|
||||
const { channels, fetchingChannels, activeChannelClaim } = props;
|
||||
|
||||
const [sigData, setSigData] = React.useState({ signature: undefined, signing_ts: undefined });
|
||||
|
||||
const hasChannels = channels && channels.length > 0;
|
||||
const activeChannelClaimStr = JSON.stringify(activeChannelClaim);
|
||||
const streamKey = createStreamKey();
|
||||
export default function LivestreamPage(props: Props) {
|
||||
const { uri, claim, doSetPlayingUri, isAuthenticated, doUserSetReferrer } = props;
|
||||
const [activeViewers, setActiveViewers] = React.useState(0);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (activeChannelClaimStr) {
|
||||
const channelClaim = JSON.parse(activeChannelClaimStr);
|
||||
// function checkIsLive() {
|
||||
// fetch(`${BITWAVE_API}/`)
|
||||
// .then((res) => res.json())
|
||||
// .then((res) => {
|
||||
// if (!res || !res.data) {
|
||||
// setIsLive(false);
|
||||
// return;
|
||||
// }
|
||||
// setActiveViewers(res.data.viewCount);
|
||||
// if (res.data.live) {
|
||||
// setDisplayCountdown(false);
|
||||
// setIsLive(true);
|
||||
// setIsFetching(false);
|
||||
// return;
|
||||
// }
|
||||
// // Not live, but see if we can display the countdown;
|
||||
// const scheduledTime = res.data.scheduled;
|
||||
// if (scheduledTime) {
|
||||
// const scheduledDate = new Date(scheduledTime);
|
||||
// const lastLiveTimestamp = res.data.timestamp;
|
||||
// let isLivestreamOver = false;
|
||||
// if (lastLiveTimestamp) {
|
||||
// const timestampDate = new Date(lastLiveTimestamp);
|
||||
// isLivestreamOver = timestampDate.getTime() > scheduledDate.getTime();
|
||||
// }
|
||||
// if (isLivestreamOver) {
|
||||
// setDisplayCountdown(false);
|
||||
// setIsLive(false);
|
||||
// } else {
|
||||
// const datePlusTenMinuteBuffer = scheduledDate.setMinutes(10, 0, 0);
|
||||
// const isInFuture = Date.now() < datePlusTenMinuteBuffer;
|
||||
// if (isInFuture) {
|
||||
// setDisplayCountdown(true);
|
||||
// setIsLive(false);
|
||||
// } else {
|
||||
// setDisplayCountdown(false);
|
||||
// setIsLive(false);
|
||||
// }
|
||||
// }
|
||||
// setIsFetching(false);
|
||||
// } else {
|
||||
// // Offline and no countdown happening
|
||||
// setIsLive(false);
|
||||
// setDisplayCountdown(false);
|
||||
// setActiveViewers(0);
|
||||
// setIsFetching(false);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// let interval;
|
||||
// checkIsLive();
|
||||
// if (uri) {
|
||||
// interval = setInterval(checkIsLive, 10000);
|
||||
// }
|
||||
// return () => {
|
||||
// if (interval) {
|
||||
// clearInterval(interval);
|
||||
// }
|
||||
// };
|
||||
}, [uri]);
|
||||
|
||||
// ensure we have a channel
|
||||
if (channelClaim.claim_id) {
|
||||
Lbry.channel_sign({
|
||||
channel_id: channelClaim.claim_id,
|
||||
hexdata: toHex(channelClaim.name),
|
||||
})
|
||||
.then((data) => {
|
||||
console.log(data);
|
||||
setSigData(data);
|
||||
})
|
||||
.catch((error) => {
|
||||
setSigData({ signature: null, signing_ts: null });
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [ activeChannelClaimStr, setSigData ]);
|
||||
const stringifiedClaim = JSON.stringify(claim);
|
||||
React.useEffect(() => {
|
||||
if (uri && stringifiedClaim) {
|
||||
const jsonClaim = JSON.parse(stringifiedClaim);
|
||||
|
||||
function createStreamKey() {
|
||||
if (!activeChannelClaim || !sigData.signature || !sigData.signing_ts) return null;
|
||||
return `${activeChannelClaim.claim_id}?d=${toHex(activeChannelClaim.name)}&s=${sigData.signature}&t=${sigData.signing_ts}`;
|
||||
if (jsonClaim) {
|
||||
const { txid, nout, claim_id: claimId } = jsonClaim;
|
||||
const outpoint = `${txid}:${nout}`;
|
||||
|
||||
analytics.apiLogView(uri, outpoint, claimId);
|
||||
}
|
||||
|
||||
/******/
|
||||
|
||||
const LIVE_STREAM_TAG = 'odysee-livestream';
|
||||
|
||||
const [isFetching, setIsFetching] = React.useState(true);
|
||||
const [isLive, setIsLive] = React.useState(false);
|
||||
const [livestreamClaim, setLivestreamClaim] = React.useState(false);
|
||||
const [livestreamClaims, setLivestreamClaims] = React.useState([]);
|
||||
if (!isAuthenticated) {
|
||||
const uri = jsonClaim.signing_channel && jsonClaim.signing_channel.permanent_url;
|
||||
if (uri) {
|
||||
doUserSetReferrer(uri.replace('lbry://', ''));
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [uri, stringifiedClaim, isAuthenticated]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!activeChannelClaimStr) return;
|
||||
|
||||
const channelClaim = JSON.parse(activeChannelClaimStr);
|
||||
|
||||
Lbry.claim_search({
|
||||
channel_ids: [channelClaim.claim_id],
|
||||
any_tags: [LIVE_STREAM_TAG],
|
||||
claim_type: ['stream'],
|
||||
})
|
||||
.then((res) => {
|
||||
if (res && res.items && res.items.length > 0) {
|
||||
const claim = res.items[res.items.length - 1];
|
||||
setLivestreamClaim(claim);
|
||||
setLivestreamClaims(res.items.reverse());
|
||||
} else {
|
||||
setIsFetching(false);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
setIsFetching(false);
|
||||
});
|
||||
}, [activeChannelClaimStr]);
|
||||
// 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>
|
||||
{fetchingChannels && (
|
||||
<div className="main--empty">
|
||||
<Spinner delayed />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!fetchingChannels && !hasChannels && (
|
||||
<Yrbl
|
||||
type="happy"
|
||||
title={__("You haven't created a channel yet, let's fix that!")}
|
||||
actions={
|
||||
<div className="section__actions">
|
||||
<Button
|
||||
button="primary"
|
||||
navigate={`/$/${PAGES.CHANNEL_NEW}`}
|
||||
label={__('Create A Channel')}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
||||
{!fetchingChannels && activeChannelClaim && (
|
||||
<React.Fragment>
|
||||
{/* Channel Selector */}
|
||||
<ChannelSelector hideAnon />
|
||||
|
||||
{/* Display StreamKey */}
|
||||
{ streamKey
|
||||
? (<div>
|
||||
{/* Stream Server Address */}
|
||||
<FormField
|
||||
name={'livestreamServer'}
|
||||
label={'Stream Server'}
|
||||
type={'text'}
|
||||
defaultValue={'rtmp://stream.odysee.com/live'}
|
||||
readOnly
|
||||
/>
|
||||
|
||||
{/* Stream Key */}
|
||||
<FormField
|
||||
name={'livestreamKey'}
|
||||
label={'Stream Key'}
|
||||
type={'text'}
|
||||
defaultValue={streamKey}
|
||||
readOnly
|
||||
/>
|
||||
</div>)
|
||||
: (
|
||||
<div>
|
||||
<div style={{marginBottom: 'var(--spacing-l)'}}>
|
||||
{JSON.stringify(activeChannelClaim)}
|
||||
</div>
|
||||
{ sigData &&
|
||||
<div>
|
||||
{JSON.stringify(sigData)}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
{/* Stream Claim(s) */}
|
||||
{ livestreamClaim && livestreamClaims ? (
|
||||
<div style={{marginTop: 'var(--spacing-l)'}}>
|
||||
<h3>Your LiveStream Claims</h3>
|
||||
|
||||
{livestreamClaims.map(claim => (
|
||||
<ClaimPreview
|
||||
key={claim.uri}
|
||||
uri={claim.permanent_url}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/*<h3>Your LiveStream Claims</h3>
|
||||
<ClaimPreview
|
||||
uri={livestreamClaim.permanent_url}
|
||||
/>*/}
|
||||
</div>
|
||||
) : (
|
||||
<div style={{marginTop: 'var(--spacing-l)'}}>
|
||||
<div>You must first publish a livestream claim before your stream will be visible!</div>
|
||||
|
||||
{/* Relies on https://github.com/lbryio/lbry-desktop/pull/5669 */}
|
||||
<Button
|
||||
button="primary"
|
||||
navigate={`/$/${PAGES.UPLOAD}?type=${PUBLISH_MODES.LIVESTREAM.toLowerCase()}`}
|
||||
label={__('Create A LiveStream')}
|
||||
/>
|
||||
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Debug Stuff */}
|
||||
{ streamKey && false && (
|
||||
<div style={{marginTop: 'var(--spacing-l)'}}>
|
||||
<h3>Debug Info</h3>
|
||||
|
||||
{/* Channel ID */}
|
||||
<FormField
|
||||
name={'channelId'}
|
||||
label={'Channel ID'}
|
||||
type={'text'}
|
||||
defaultValue={activeChannelClaim.claim_id}
|
||||
readOnly
|
||||
/>
|
||||
|
||||
{/* Signature */}
|
||||
<FormField
|
||||
name={'signature'}
|
||||
label={'Signature'}
|
||||
type={'text'}
|
||||
defaultValue={sigData.signature}
|
||||
readOnly
|
||||
/>
|
||||
|
||||
{/* Signature TS */}
|
||||
<FormField
|
||||
name={'signaturets'}
|
||||
label={'Signature Timestamp'}
|
||||
type={'text'}
|
||||
defaultValue={sigData.signing_ts}
|
||||
readOnly
|
||||
/>
|
||||
|
||||
{/* Hex Data */}
|
||||
<FormField
|
||||
name={'datahex'}
|
||||
label={'Hex Data'}
|
||||
type={'text'}
|
||||
defaultValue={toHex(activeChannelClaim.name)}
|
||||
readOnly
|
||||
/>
|
||||
|
||||
{/* Channel Public Key */}
|
||||
<FormField
|
||||
name={'channelpublickey'}
|
||||
label={'Public Key'}
|
||||
type={'text'}
|
||||
defaultValue={activeChannelClaim.value.public_key}
|
||||
readOnly
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</React.Fragment>
|
||||
)}
|
||||
<Page className="file-page" filePage livestream>
|
||||
<LivestreamLayout uri={uri} activeViewers={activeViewers} />
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
|
12
ui/page/livestreamSetup/index.js
Normal file
12
ui/page/livestreamSetup/index.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { selectMyChannelClaims, selectFetchingMyChannels } from 'lbry-redux';
|
||||
import { selectActiveChannelClaim } from 'redux/selectors/app';
|
||||
import LivestreamSetupPage from './view';
|
||||
|
||||
const select = (state) => ({
|
||||
channels: selectMyChannelClaims(state),
|
||||
fetchingChannels: selectFetchingMyChannels(state),
|
||||
activeChannelClaim: selectActiveChannelClaim(state),
|
||||
});
|
||||
|
||||
export default connect(select)(LivestreamSetupPage);
|
221
ui/page/livestreamSetup/view.jsx
Normal file
221
ui/page/livestreamSetup/view.jsx
Normal file
|
@ -0,0 +1,221 @@
|
|||
// @flow
|
||||
import * as PAGES from 'constants/pages';
|
||||
import React from 'react';
|
||||
import Page from 'component/page';
|
||||
import Spinner from 'component/spinner';
|
||||
import Button from 'component/button';
|
||||
import ChannelSelector from 'component/channelSelector';
|
||||
import Yrbl from 'component/yrbl';
|
||||
import { Lbry } from 'lbry-redux';
|
||||
import { toHex } from 'util/hex';
|
||||
import ClaimPreview from 'component/claimPreview';
|
||||
import { FormField } from 'component/common/form';
|
||||
import * as PUBLISH_MODES from 'constants/publish_types';
|
||||
|
||||
type Props = {
|
||||
channels: Array<ChannelClaim>,
|
||||
fetchingChannels: boolean,
|
||||
activeChannelClaim: ?ChannelClaim,
|
||||
};
|
||||
|
||||
export default function LivestreamSetupPage(props: Props) {
|
||||
const { channels, fetchingChannels, activeChannelClaim } = props;
|
||||
|
||||
const [sigData, setSigData] = React.useState({ signature: undefined, signing_ts: undefined });
|
||||
|
||||
const hasChannels = channels && channels.length > 0;
|
||||
const activeChannelClaimStr = JSON.stringify(activeChannelClaim);
|
||||
const streamKey = createStreamKey();
|
||||
|
||||
React.useEffect(() => {
|
||||
if (activeChannelClaimStr) {
|
||||
const channelClaim = JSON.parse(activeChannelClaimStr);
|
||||
|
||||
// ensure we have a channel
|
||||
if (channelClaim.claim_id) {
|
||||
Lbry.channel_sign({
|
||||
channel_id: channelClaim.claim_id,
|
||||
hexdata: toHex(channelClaim.name),
|
||||
})
|
||||
.then((data) => {
|
||||
console.log(data);
|
||||
setSigData(data);
|
||||
})
|
||||
.catch((error) => {
|
||||
setSigData({ signature: null, signing_ts: null });
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [activeChannelClaimStr, setSigData]);
|
||||
|
||||
function createStreamKey() {
|
||||
if (!activeChannelClaim || !sigData.signature || !sigData.signing_ts) return null;
|
||||
return `${activeChannelClaim.claim_id}?d=${toHex(activeChannelClaim.name)}&s=${sigData.signature}&t=${
|
||||
sigData.signing_ts
|
||||
}`;
|
||||
}
|
||||
|
||||
/******/
|
||||
|
||||
const LIVE_STREAM_TAG = 'odysee-livestream';
|
||||
|
||||
const [isFetching, setIsFetching] = React.useState(true);
|
||||
const [isLive, setIsLive] = React.useState(false);
|
||||
const [livestreamClaim, setLivestreamClaim] = React.useState(false);
|
||||
const [livestreamClaims, setLivestreamClaims] = React.useState([]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!activeChannelClaimStr) return;
|
||||
|
||||
const channelClaim = JSON.parse(activeChannelClaimStr);
|
||||
|
||||
Lbry.claim_search({
|
||||
channel_ids: [channelClaim.claim_id],
|
||||
any_tags: [LIVE_STREAM_TAG],
|
||||
claim_type: ['stream'],
|
||||
})
|
||||
.then((res) => {
|
||||
if (res && res.items && res.items.length > 0) {
|
||||
const claim = res.items[res.items.length - 1];
|
||||
setLivestreamClaim(claim);
|
||||
setLivestreamClaims(res.items.reverse());
|
||||
} else {
|
||||
setIsFetching(false);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
setIsFetching(false);
|
||||
});
|
||||
}, [activeChannelClaimStr]);
|
||||
|
||||
return (
|
||||
<Page>
|
||||
{fetchingChannels && (
|
||||
<div className="main--empty">
|
||||
<Spinner delayed />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!fetchingChannels && !hasChannels && (
|
||||
<Yrbl
|
||||
type="happy"
|
||||
title={__("You haven't created a channel yet, let's fix that!")}
|
||||
actions={
|
||||
<div className="section__actions">
|
||||
<Button button="primary" navigate={`/$/${PAGES.CHANNEL_NEW}`} label={__('Create A Channel')} />
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
||||
{!fetchingChannels && activeChannelClaim && (
|
||||
<React.Fragment>
|
||||
{/* Channel Selector */}
|
||||
<ChannelSelector hideAnon />
|
||||
|
||||
{/* Display StreamKey */}
|
||||
{streamKey ? (
|
||||
<div>
|
||||
{/* Stream Server Address */}
|
||||
<FormField
|
||||
name={'livestreamServer'}
|
||||
label={'Stream Server'}
|
||||
type={'text'}
|
||||
defaultValue={'rtmp://stream.odysee.com/live'}
|
||||
readOnly
|
||||
/>
|
||||
|
||||
{/* Stream Key */}
|
||||
<FormField name={'livestreamKey'} label={'Stream Key'} type={'text'} defaultValue={streamKey} readOnly />
|
||||
</div>
|
||||
) : (
|
||||
<div>
|
||||
<div style={{ marginBottom: 'var(--spacing-l)' }}>{JSON.stringify(activeChannelClaim)}</div>
|
||||
{sigData && <div>{JSON.stringify(sigData)}</div>}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Stream Claim(s) */}
|
||||
{livestreamClaim && livestreamClaims ? (
|
||||
<div style={{ marginTop: 'var(--spacing-l)' }}>
|
||||
<h3>Your LiveStream Claims</h3>
|
||||
|
||||
{livestreamClaims.map((claim) => (
|
||||
<ClaimPreview key={claim.uri} uri={claim.permanent_url} />
|
||||
))}
|
||||
|
||||
{/*<h3>Your LiveStream Claims</h3>
|
||||
<ClaimPreview
|
||||
uri={livestreamClaim.permanent_url}
|
||||
/>*/}
|
||||
</div>
|
||||
) : (
|
||||
<div style={{ marginTop: 'var(--spacing-l)' }}>
|
||||
<div>You must first publish a livestream claim before your stream will be visible!</div>
|
||||
|
||||
{/* Relies on https://github.com/lbryio/lbry-desktop/pull/5669 */}
|
||||
<Button
|
||||
button="primary"
|
||||
navigate={`/$/${PAGES.UPLOAD}?type=${PUBLISH_MODES.LIVESTREAM.toLowerCase()}`}
|
||||
label={__('Create A LiveStream')}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Debug Stuff */}
|
||||
{streamKey && false && (
|
||||
<div style={{ marginTop: 'var(--spacing-l)' }}>
|
||||
<h3>Debug Info</h3>
|
||||
|
||||
{/* Channel ID */}
|
||||
<FormField
|
||||
name={'channelId'}
|
||||
label={'Channel ID'}
|
||||
type={'text'}
|
||||
defaultValue={activeChannelClaim.claim_id}
|
||||
readOnly
|
||||
/>
|
||||
|
||||
{/* Signature */}
|
||||
<FormField
|
||||
name={'signature'}
|
||||
label={'Signature'}
|
||||
type={'text'}
|
||||
defaultValue={sigData.signature}
|
||||
readOnly
|
||||
/>
|
||||
|
||||
{/* Signature TS */}
|
||||
<FormField
|
||||
name={'signaturets'}
|
||||
label={'Signature Timestamp'}
|
||||
type={'text'}
|
||||
defaultValue={sigData.signing_ts}
|
||||
readOnly
|
||||
/>
|
||||
|
||||
{/* Hex Data */}
|
||||
<FormField
|
||||
name={'datahex'}
|
||||
label={'Hex Data'}
|
||||
type={'text'}
|
||||
defaultValue={toHex(activeChannelClaim.name)}
|
||||
readOnly
|
||||
/>
|
||||
|
||||
{/* Channel Public Key */}
|
||||
<FormField
|
||||
name={'channelpublickey'}
|
||||
label={'Public Key'}
|
||||
type={'text'}
|
||||
defaultValue={activeChannelClaim.value.public_key}
|
||||
readOnly
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</React.Fragment>
|
||||
)}
|
||||
</Page>
|
||||
);
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { doResolveUri } from 'lbry-redux';
|
||||
import { doSetPlayingUri } from 'redux/actions/content';
|
||||
import { doUserSetReferrer } from 'redux/actions/user';
|
||||
import { selectUserVerifiedEmail } from 'redux/selectors/user';
|
||||
import { selectHasUnclaimedRefereeReward } from 'redux/selectors/rewards';
|
||||
import LivestreamPage from './view';
|
||||
|
||||
const select = (state) => ({
|
||||
hasUnclaimedRefereeReward: selectHasUnclaimedRefereeReward(state),
|
||||
isAuthenticated: selectUserVerifiedEmail(state),
|
||||
});
|
||||
|
||||
export default connect(select, {
|
||||
doSetPlayingUri,
|
||||
doResolveUri,
|
||||
doUserSetReferrer,
|
||||
})(LivestreamPage);
|
|
@ -1,114 +0,0 @@
|
|||
// @flow
|
||||
// import { LIVE_STREAM_TAG, BITWAVE_API } from 'constants/livestream';
|
||||
import React from 'react';
|
||||
import Page from 'component/page';
|
||||
import LivestreamLayout from 'component/livestreamLayout';
|
||||
import analytics from 'analytics';
|
||||
|
||||
type Props = {
|
||||
uri: string,
|
||||
claim: StreamClaim,
|
||||
doSetPlayingUri: ({ uri: ?string }) => void,
|
||||
isAuthenticated: boolean,
|
||||
doUserSetReferrer: (string) => void,
|
||||
};
|
||||
|
||||
export default function LivestreamPage(props: Props) {
|
||||
const { uri, claim, doSetPlayingUri, isAuthenticated, doUserSetReferrer } = props;
|
||||
const [activeViewers, setActiveViewers] = React.useState(0);
|
||||
|
||||
React.useEffect(() => {
|
||||
// function checkIsLive() {
|
||||
// fetch(`${BITWAVE_API}/`)
|
||||
// .then((res) => res.json())
|
||||
// .then((res) => {
|
||||
// if (!res || !res.data) {
|
||||
// setIsLive(false);
|
||||
// return;
|
||||
// }
|
||||
// setActiveViewers(res.data.viewCount);
|
||||
// if (res.data.live) {
|
||||
// setDisplayCountdown(false);
|
||||
// setIsLive(true);
|
||||
// setIsFetching(false);
|
||||
// return;
|
||||
// }
|
||||
// // Not live, but see if we can display the countdown;
|
||||
// const scheduledTime = res.data.scheduled;
|
||||
// if (scheduledTime) {
|
||||
// const scheduledDate = new Date(scheduledTime);
|
||||
// const lastLiveTimestamp = res.data.timestamp;
|
||||
// let isLivestreamOver = false;
|
||||
// if (lastLiveTimestamp) {
|
||||
// const timestampDate = new Date(lastLiveTimestamp);
|
||||
// isLivestreamOver = timestampDate.getTime() > scheduledDate.getTime();
|
||||
// }
|
||||
// if (isLivestreamOver) {
|
||||
// setDisplayCountdown(false);
|
||||
// setIsLive(false);
|
||||
// } else {
|
||||
// const datePlusTenMinuteBuffer = scheduledDate.setMinutes(10, 0, 0);
|
||||
// const isInFuture = Date.now() < datePlusTenMinuteBuffer;
|
||||
// if (isInFuture) {
|
||||
// setDisplayCountdown(true);
|
||||
// setIsLive(false);
|
||||
// } else {
|
||||
// setDisplayCountdown(false);
|
||||
// setIsLive(false);
|
||||
// }
|
||||
// }
|
||||
// setIsFetching(false);
|
||||
// } else {
|
||||
// // Offline and no countdown happening
|
||||
// setIsLive(false);
|
||||
// setDisplayCountdown(false);
|
||||
// setActiveViewers(0);
|
||||
// setIsFetching(false);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// let interval;
|
||||
// checkIsLive();
|
||||
// if (uri) {
|
||||
// interval = setInterval(checkIsLive, 10000);
|
||||
// }
|
||||
// return () => {
|
||||
// if (interval) {
|
||||
// clearInterval(interval);
|
||||
// }
|
||||
// };
|
||||
}, [uri]);
|
||||
|
||||
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} />
|
||||
</Page>
|
||||
);
|
||||
}
|
Loading…
Reference in a new issue