Also add support for embeds
This commit is contained in:
parent
6b2427768c
commit
239bde0752
6 changed files with 93 additions and 17 deletions
|
@ -55,6 +55,7 @@ const oneTrustScriptSrc = 'https://cdn.cookielaw.org/scripttemplates/otSDKStub.j
|
|||
|
||||
const LATEST_PATH = `/$/${PAGES.LATEST}/`;
|
||||
const LIVE_PATH = `/$/${PAGES.LIVE_NOW}/`;
|
||||
const EMBED_PATH = `/$/${PAGES.EMBED}/`;
|
||||
|
||||
type Props = {
|
||||
language: string,
|
||||
|
@ -143,7 +144,7 @@ function App(props: Props) {
|
|||
const rawReferrerParam = urlParams.get('r');
|
||||
const fromLbrytvParam = urlParams.get('sunset');
|
||||
const sanitizedReferrerParam = rawReferrerParam && rawReferrerParam.replace(':', '#');
|
||||
const embedPath = pathname.startsWith(`/$/${PAGES.EMBED}`);
|
||||
const embedPath = pathname.startsWith(EMBED_PATH);
|
||||
const shouldHideNag = embedPath || pathname.startsWith(`/$/${PAGES.AUTH_VERIFY}`);
|
||||
const userId = user && user.id;
|
||||
const hasMyChannels = myChannelClaimIds && myChannelClaimIds.length > 0;
|
||||
|
@ -156,11 +157,13 @@ function App(props: Props) {
|
|||
const urlPath = pathname + hash;
|
||||
const latestContentPath = urlPath.startsWith(LATEST_PATH);
|
||||
const liveContentPath = urlPath.startsWith(LIVE_PATH);
|
||||
const isNewestPath = latestContentPath || liveContentPath;
|
||||
const featureParam = urlParams.get('feature');
|
||||
const embedLatestPath = embedPath && (featureParam === PAGES.LATEST || featureParam === PAGES.LIVE_NOW);
|
||||
const isNewestPath = latestContentPath || liveContentPath || embedLatestPath;
|
||||
|
||||
let path;
|
||||
if (isNewestPath) {
|
||||
path = urlPath.replace(latestContentPath ? LATEST_PATH : LIVE_PATH, '');
|
||||
path = urlPath.replace(embedLatestPath ? EMBED_PATH : latestContentPath ? LATEST_PATH : LIVE_PATH, '');
|
||||
} else {
|
||||
// Remove the leading "/" added by the browser
|
||||
path = urlPath.slice(1);
|
||||
|
@ -515,7 +518,7 @@ function App(props: Props) {
|
|||
/>
|
||||
) : (
|
||||
<React.Fragment>
|
||||
<Router uri={uri} />
|
||||
<Router uri={uri} embedLatestPath={embedLatestPath} />
|
||||
<ModalRouter />
|
||||
|
||||
<React.Suspense fallback={null}>{renderFiledrop && <FileDrop />}</React.Suspense>
|
||||
|
|
|
@ -136,6 +136,7 @@ type Props = {
|
|||
hideTitleNotificationCount: boolean,
|
||||
hasDefaultChannel: boolean,
|
||||
doSetActiveChannel: (claimId: ?string, override?: boolean) => void,
|
||||
embedLatestPath: ?boolean,
|
||||
};
|
||||
|
||||
type PrivateRouteProps = Props & {
|
||||
|
@ -179,6 +180,7 @@ function AppRouter(props: Props) {
|
|||
hideTitleNotificationCount,
|
||||
hasDefaultChannel,
|
||||
doSetActiveChannel,
|
||||
embedLatestPath,
|
||||
} = props;
|
||||
|
||||
const defaultChannelRef = React.useRef(hasDefaultChannel);
|
||||
|
@ -397,7 +399,11 @@ function AppRouter(props: Props) {
|
|||
|
||||
<Route path={`/$/${PAGES.POPOUT}/:channelName/:streamName`} component={PopoutChatPage} />
|
||||
|
||||
<Route path={`/$/${PAGES.EMBED}/:claimName`} exact component={EmbedWrapperPage} />
|
||||
<Route
|
||||
path={`/$/${PAGES.EMBED}/:claimName`}
|
||||
exact
|
||||
component={embedLatestPath ? () => <EmbedWrapperPage uri={uri} /> : EmbedWrapperPage}
|
||||
/>
|
||||
<Route path={`/$/${PAGES.EMBED}/:claimName/:claimId`} exact component={EmbedWrapperPage} />
|
||||
|
||||
{/* Below need to go at the end to make sure we don't match any of our pages first */}
|
||||
|
|
|
@ -1,31 +1,60 @@
|
|||
import { connect } from 'react-redux';
|
||||
import EmbedWrapperPage from './view';
|
||||
import { selectClaimForUri, selectIsUriResolving, selectGeoRestrictionForUri } from 'redux/selectors/claims';
|
||||
import * as PAGES from 'constants/pages';
|
||||
import {
|
||||
selectClaimForUri,
|
||||
selectIsUriResolving,
|
||||
selectGeoRestrictionForUri,
|
||||
selectLatestClaimByUri,
|
||||
} from 'redux/selectors/claims';
|
||||
import { makeSelectStreamingUrlForUri } from 'redux/selectors/file_info';
|
||||
import { doResolveUri } from 'redux/actions/claims';
|
||||
import { doResolveUri, doFetchLatestClaimForChannel } from 'redux/actions/claims';
|
||||
import { buildURI } from 'util/lbryURI';
|
||||
import { doPlayUri } from 'redux/actions/content';
|
||||
import { selectShouldObscurePreviewForUri } from 'redux/selectors/content';
|
||||
import { selectCostInfoForUri, doFetchCostInfoForUri, selectBlackListedOutpoints } from 'lbryinc';
|
||||
import { doCommentSocketConnect, doCommentSocketDisconnect } from 'redux/actions/websocket';
|
||||
import { doFetchActiveLivestreams, doFetchChannelLiveStatus } from 'redux/actions/livestream';
|
||||
import { selectIsActiveLivestreamForUri, selectActiveLivestreamInitialized } from 'redux/selectors/livestream';
|
||||
import {
|
||||
selectIsActiveLivestreamForUri,
|
||||
selectActiveLivestreamInitialized,
|
||||
selectActiveLiveClaimForChannel,
|
||||
} from 'redux/selectors/livestream';
|
||||
import { getThumbnailFromClaim, isStreamPlaceholderClaim } from 'util/claim';
|
||||
import { doUserSetReferrerWithUri } from 'redux/actions/user';
|
||||
|
||||
const select = (state, props) => {
|
||||
const { match } = props;
|
||||
const { search } = state.router.location;
|
||||
const { match } = props || {};
|
||||
|
||||
let uri = props.uri;
|
||||
let claimId;
|
||||
if (match) {
|
||||
const { params } = match;
|
||||
const { claimName, claimId } = params;
|
||||
const uri = claimName ? buildURI({ claimName, claimId }) : '';
|
||||
const { claimName } = params;
|
||||
claimId = params.claimId;
|
||||
uri = claimName ? buildURI({ claimName, claimId }) : '';
|
||||
}
|
||||
|
||||
const urlParams = new URLSearchParams(search);
|
||||
const featureParam = urlParams.get('feature');
|
||||
const isNewestPath = featureParam === PAGES.LIVE_NOW || featureParam === PAGES.LATEST;
|
||||
|
||||
const claim = selectClaimForUri(state, uri);
|
||||
const { canonical_url: canonicalUrl, signing_channel: channelClaim, txid, nout } = claim || {};
|
||||
if (isNewestPath) claimId = claim?.claim_id;
|
||||
|
||||
const { claim_id: channelClaimId, canonical_url: channelUri, txid: channelTxid, channelNout } = channelClaim || {};
|
||||
const haveClaim = Boolean(claim);
|
||||
const nullClaim = claim === null;
|
||||
|
||||
const latestContentClaim =
|
||||
featureParam === PAGES.LIVE_NOW
|
||||
? selectActiveLiveClaimForChannel(state, claimId)
|
||||
: selectLatestClaimByUri(state, canonicalUrl);
|
||||
const latestClaimUrl = latestContentClaim && latestContentClaim.canonical_url;
|
||||
if (latestClaimUrl) uri = latestClaimUrl;
|
||||
|
||||
return {
|
||||
uri,
|
||||
claimId,
|
||||
|
@ -38,11 +67,13 @@ const select = (state, props) => {
|
|||
channelClaimId,
|
||||
channelTxid,
|
||||
channelNout,
|
||||
latestClaimUrl,
|
||||
isNewestPath,
|
||||
costInfo: uri && selectCostInfoForUri(state, uri),
|
||||
streamingUrl: uri && makeSelectStreamingUrlForUri(uri)(state),
|
||||
isResolvingUri: uri && selectIsUriResolving(state, uri),
|
||||
blackListedOutpoints: haveClaim && selectBlackListedOutpoints(state),
|
||||
isCurrentClaimLive: canonicalUrl && selectIsActiveLivestreamForUri(state, canonicalUrl),
|
||||
isCurrentClaimLive: selectIsActiveLivestreamForUri(state, isNewestPath ? latestClaimUrl : canonicalUrl),
|
||||
isLivestreamClaim: isStreamPlaceholderClaim(claim),
|
||||
obscurePreview: selectShouldObscurePreviewForUri(state, uri),
|
||||
claimThumbnail: getThumbnailFromClaim(claim),
|
||||
|
@ -60,6 +91,7 @@ const perform = {
|
|||
doCommentSocketDisconnect,
|
||||
doFetchActiveLivestreams,
|
||||
setReferrer: doUserSetReferrerWithUri,
|
||||
fetchLatestClaimForChannel: doFetchLatestClaimForChannel,
|
||||
};
|
||||
|
||||
export default connect(select, perform)(EmbedWrapperPage);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
import { SITE_NAME } from 'config';
|
||||
import * as PAGES from 'constants/pages';
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import FileRender from 'component/fileRender';
|
||||
|
@ -36,6 +37,9 @@ type Props = {
|
|||
obscurePreview: boolean,
|
||||
activeLivestreamInitialized: boolean,
|
||||
geoRestriction: ?GeoRestriction,
|
||||
latestClaimUrl: ?string,
|
||||
isNewestPath: ?boolean,
|
||||
fetchLatestClaimForChannel: (uri: string, isEmbed: boolean) => void,
|
||||
doResolveUri: (uri: string) => void,
|
||||
doPlayUri: (uri: string) => void,
|
||||
doFetchCostInfoForUri: (uri: string) => void,
|
||||
|
@ -71,6 +75,9 @@ export default function EmbedWrapperPage(props: Props) {
|
|||
obscurePreview,
|
||||
activeLivestreamInitialized,
|
||||
geoRestriction,
|
||||
latestClaimUrl,
|
||||
isNewestPath,
|
||||
fetchLatestClaimForChannel,
|
||||
doResolveUri,
|
||||
doPlayUri,
|
||||
doFetchCostInfoForUri,
|
||||
|
@ -90,6 +97,9 @@ export default function EmbedWrapperPage(props: Props) {
|
|||
|
||||
const channelUrl = channelUri && formatLbryChannelName(channelUri);
|
||||
const urlParams = new URLSearchParams(search);
|
||||
const featureParam = urlParams.get('feature');
|
||||
const latestContentPath = featureParam === PAGES.LATEST;
|
||||
const liveContentPath = featureParam === PAGES.LIVE_NOW;
|
||||
const rawReferrerParam = urlParams.get('r');
|
||||
const sanitizedReferrerParam = rawReferrerParam && rawReferrerParam.replace(':', '#');
|
||||
const embedLightBackground = urlParams.get('embedBackgroundLight');
|
||||
|
@ -111,6 +121,18 @@ export default function EmbedWrapperPage(props: Props) {
|
|||
|
||||
const thumbnail = useThumbnail(claimThumbnail, containerRef);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!latestClaimUrl && liveContentPath && claimId) {
|
||||
doFetchChannelLiveStatus(claimId);
|
||||
}
|
||||
}, [claimId, doFetchChannelLiveStatus, latestClaimUrl, liveContentPath]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!latestClaimUrl && latestContentPath && canonicalUrl) {
|
||||
fetchLatestClaimForChannel(canonicalUrl, true);
|
||||
}
|
||||
}, [canonicalUrl, fetchLatestClaimForChannel, latestClaimUrl, latestContentPath]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!sanitizedReferrerParam) setReferrer(uri);
|
||||
}, [sanitizedReferrerParam, setReferrer, uri]);
|
||||
|
@ -142,10 +164,10 @@ export default function EmbedWrapperPage(props: Props) {
|
|||
doResolveUri(uri);
|
||||
}
|
||||
|
||||
if (uri && haveClaim && costInfo && costInfo.cost === 0) {
|
||||
if (uri && (isNewestPath ? latestClaimUrl : haveClaim) && costInfo && costInfo.cost === 0) {
|
||||
doPlayUri(uri);
|
||||
}
|
||||
}, [doPlayUri, doResolveUri, haveClaim, costInfo, uri]);
|
||||
}, [doPlayUri, doResolveUri, haveClaim, costInfo, uri, isNewestPath, latestClaimUrl]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (haveClaim && uri && doFetchCostInfoForUri) {
|
||||
|
@ -155,6 +177,15 @@ export default function EmbedWrapperPage(props: Props) {
|
|||
|
||||
useFetchLiveStatus(livestreamsFetched ? channelClaimId : undefined, doFetchChannelLiveStatus);
|
||||
|
||||
// Wait for latest claim fetch
|
||||
if (isNewestPath && latestClaimUrl === undefined) {
|
||||
return (
|
||||
<div className="main--empty">
|
||||
<Spinner delayed />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (isClaimBlackListed) {
|
||||
return (
|
||||
<Card
|
||||
|
|
|
@ -1135,7 +1135,10 @@ export const doCheckPendingClaims = (onChannelConfirmed: Function) => (dispatch:
|
|||
}, 30000);
|
||||
};
|
||||
|
||||
export const doFetchLatestClaimForChannel = (uri: string) => (dispatch: Dispatch, getState: GetState) => {
|
||||
export const doFetchLatestClaimForChannel = (uri: string, isEmbed?: boolean) => (
|
||||
dispatch: Dispatch,
|
||||
getState: GetState
|
||||
) => {
|
||||
const searchOptions = {
|
||||
limit_claims_per_channel: 1,
|
||||
channel: uri,
|
||||
|
@ -1143,6 +1146,7 @@ export const doFetchLatestClaimForChannel = (uri: string) => (dispatch: Dispatch
|
|||
order_by: ['release_time'],
|
||||
page: 1,
|
||||
has_source: true,
|
||||
stream_types: isEmbed ? ['audio', 'video'] : undefined,
|
||||
};
|
||||
|
||||
return dispatch(doClaimSearch(searchOptions))
|
||||
|
|
|
@ -66,7 +66,7 @@ export const selectIsActiveLivestreamForUri = createCachedSelector(
|
|||
|
||||
const activeLivestreamValues = Object.values(activeLivestreams);
|
||||
// $FlowFixMe - unable to resolve claimUri
|
||||
return activeLivestreamValues.some((v) => v.claimUri === uri);
|
||||
return activeLivestreamValues.some((v) => v?.claimUri === uri);
|
||||
}
|
||||
)((state, uri) => String(uri));
|
||||
|
||||
|
|
Loading…
Reference in a new issue