lbry-desktop/ui/component/fileRenderMobile/view.jsx
Rafael 8c3e376873 File Page and Player style changes on mobile view
- Biggest change: Moved mobile player logic outside of fileRenderFloating into its own component fileRenderMobile, since there is no need for all that extra resizing and dragging code (for now, as mobile doesn't have a floating player)
- Moved player to the header height
- Removed rounded borders and margins
2022-02-08 12:35:40 -05:00

177 lines
5.4 KiB
JavaScript

// @flow
import * as RENDER_MODES from 'constants/file_render_modes';
import React, { useEffect, useState } from 'react';
import { onFullscreenChange } from 'util/full-screen';
import { generateListSearchUrlParams, formatLbryUrlForWeb } from 'util/url';
import { useHistory } from 'react-router';
import LoadingScreen from 'component/common/loading-screen';
import FileRender from 'component/fileRender';
import AutoplayCountdown from 'component/autoplayCountdown';
import LivestreamIframeRender from 'component/livestreamLayout/iframe-render';
const PRIMARY_PLAYER_WRAPPER_CLASS = 'file-page__video-container';
export const INLINE_PLAYER_WRAPPER_CLASS = 'inline-player__wrapper';
// ****************************************************************************
// ****************************************************************************
type Props = {
claimId?: string,
uri: string,
streamingUrl?: string,
renderMode: string,
collectionId: string,
costInfo: any,
claimWasPurchased: boolean,
nextListUri: string,
previousListUri: string,
activeLivestreamForChannel?: any,
channelClaimId?: any,
doPlayUri: (string) => void,
};
export default function FileRenderMobile(props: Props) {
const {
claimId,
uri,
streamingUrl,
renderMode,
collectionId,
costInfo,
claimWasPurchased,
nextListUri,
previousListUri,
activeLivestreamForChannel,
channelClaimId,
doPlayUri,
} = props;
const { push } = useHistory();
const [fileViewerRect, setFileViewerRect] = useState();
const [doNavigate, setDoNavigate] = useState(false);
const [playNextUrl, setPlayNextUrl] = useState(true);
const [countdownCanceled, setCountdownCanceled] = useState(false);
const isCurrentClaimLive = activeLivestreamForChannel && activeLivestreamForChannel.claimId === claimId;
const isFree = costInfo && costInfo.cost === 0;
const canViewFile = isFree || claimWasPurchased;
const isPlayable = RENDER_MODES.FLOATING_MODES.includes(renderMode) || activeLivestreamForChannel;
const isReadyToPlay = isPlayable && streamingUrl;
const handleResize = React.useCallback(() => {
const element = document.querySelector(`.${PRIMARY_PLAYER_WRAPPER_CLASS}`);
if (!element) return;
const rect = element.getBoundingClientRect();
// getBoundingClientRect returns a DomRect, not an object
const objectRect = {
top: rect.top,
right: rect.right,
bottom: rect.bottom,
left: rect.left,
width: rect.width,
height: rect.height,
// $FlowFixMe
x: rect.x,
};
// $FlowFixMe
setFileViewerRect({ ...objectRect });
}, []);
// Initial resize, will place the player correctly above the cover when starts playing
// (remember the URI here is from playingUri). The cover then keeps on the page and kind of serves as a placeholder
// for the player size and gives the content layered behind the player a "max scroll height"
useEffect(() => {
if (uri) {
handleResize();
setCountdownCanceled(false);
}
}, [handleResize, uri]);
useEffect(() => {
handleResize();
window.addEventListener('resize', handleResize);
onFullscreenChange(window, 'add', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
onFullscreenChange(window, 'remove', handleResize);
};
}, [handleResize]);
const doPlay = React.useCallback(
(playUri) => {
setDoNavigate(false);
const navigateUrl = formatLbryUrlForWeb(playUri);
push({
pathname: navigateUrl,
search: collectionId && generateListSearchUrlParams(collectionId),
state: { collectionId, forceAutoplay: true, hideFloatingPlayer: true },
});
},
[collectionId, push]
);
React.useEffect(() => {
if (!doNavigate) return;
if (playNextUrl && nextListUri) {
doPlay(nextListUri);
} else if (previousListUri) {
doPlay(previousListUri);
}
setPlayNextUrl(true);
}, [doNavigate, doPlay, nextListUri, playNextUrl, previousListUri]);
if (!isPlayable || !uri || countdownCanceled || (collectionId && !canViewFile && !nextListUri)) {
return null;
}
return (
<div
className="content__viewer content__viewer--inline content__viewer--mobile"
style={
fileViewerRect
? {
width: fileViewerRect.width,
height: fileViewerRect.height,
left: fileViewerRect.x,
}
: {}
}
>
<div className="content__wrapper">
<React.Suspense fallback={<Loading />}>
{isCurrentClaimLive && channelClaimId ? (
<LivestreamIframeRender channelClaimId={channelClaimId} showLivestream mobileVersion />
) : isReadyToPlay ? (
<FileRender uri={uri} />
) : !canViewFile ? (
<div className="content__loading">
<AutoplayCountdown
nextRecommendedUri={nextListUri}
doNavigate={() => setDoNavigate(true)}
doReplay={() => doPlayUri(uri)}
doPrevious={() => {
setPlayNextUrl(false);
setDoNavigate(true);
}}
onCanceled={() => setCountdownCanceled(true)}
skipPaid
/>
</div>
) : (
<Loading />
)}
</React.Suspense>
</div>
</div>
);
}
const Loading = () => <LoadingScreen status={__('Loading')} />;