Add Play Previous Button

This commit is contained in:
saltrafael 2021-08-25 08:25:55 -03:00 committed by zeppi
parent 73722a4f00
commit bd64d5c9ea
3 changed files with 57 additions and 15 deletions

View file

@ -6,6 +6,7 @@ import {
SETTINGS, SETTINGS,
COLLECTIONS_CONSTS, COLLECTIONS_CONSTS,
makeSelectNextUrlForCollectionAndUrl, makeSelectNextUrlForCollectionAndUrl,
makeSelectPreviousUrlForCollectionAndUrl,
} from 'lbry-redux'; } from 'lbry-redux';
import { doChangeVolume, doChangeMute, doAnalyticsView, doAnalyticsBuffer } from 'redux/actions/app'; import { doChangeVolume, doChangeMute, doAnalyticsView, doAnalyticsBuffer } from 'redux/actions/app';
import { selectVolume, selectMute } from 'redux/selectors/app'; import { selectVolume, selectMute } from 'redux/selectors/app';
@ -33,8 +34,10 @@ const select = (state, props) => {
const collectionId = urlParams.get(COLLECTIONS_CONSTS.COLLECTION_ID) || (playingUri && playingUri.collectionId); const collectionId = urlParams.get(COLLECTIONS_CONSTS.COLLECTION_ID) || (playingUri && playingUri.collectionId);
let playNextUri; let playNextUri;
let playPreviousUri;
if (collectionId) { if (collectionId) {
playNextUri = makeSelectNextUrlForCollectionAndUrl(collectionId, props.uri)(state); playNextUri = makeSelectNextUrlForCollectionAndUrl(collectionId, props.uri)(state);
playPreviousUri = makeSelectPreviousUrlForCollectionAndUrl(collectionId, props.uri)(state);
} }
return { return {
@ -55,6 +58,7 @@ const select = (state, props) => {
isFloating: makeSelectIsPlayerFloating(props.location)(state), isFloating: makeSelectIsPlayerFloating(props.location)(state),
collectionId, collectionId,
playNextUri, playNextUri,
playPreviousUri,
}; };
}; };

View file

@ -49,7 +49,7 @@ type Props = {
source: string, source: string,
sourceType: string, sourceType: string,
poster: ?string, poster: ?string,
onPlayerReady: (Player) => void, onPlayerReady: (Player, any) => void,
isAudio: boolean, isAudio: boolean,
startMuted: boolean, startMuted: boolean,
autoplay: boolean, autoplay: boolean,
@ -61,6 +61,7 @@ type Props = {
shareTelemetry: boolean, shareTelemetry: boolean,
replay: boolean, replay: boolean,
videoTheaterMode: boolean, videoTheaterMode: boolean,
setStartPlayPrevious: (boolean) => void,
setStartPlayNext: (boolean) => void, setStartPlayNext: (boolean) => void,
}; };
@ -106,6 +107,7 @@ const SMALL_J_KEYCODE = 74;
const SMALL_K_KEYCODE = 75; const SMALL_K_KEYCODE = 75;
const SMALL_L_KEYCODE = 76; const SMALL_L_KEYCODE = 76;
const P_KEYCODE = 80;
const N_KEYCODE = 78; const N_KEYCODE = 78;
const ZERO_KEYCODE = 48; const ZERO_KEYCODE = 48;
@ -215,6 +217,7 @@ export default React.memo<Props>(function VideoJs(props: Props) {
shareTelemetry, shareTelemetry,
replay, replay,
videoTheaterMode, videoTheaterMode,
setStartPlayPrevious,
setStartPlayNext, setStartPlayNext,
} = props; } = props;
@ -404,6 +407,7 @@ export default React.memo<Props>(function VideoJs(props: Props) {
if (e.altKey || e.ctrlKey || e.metaKey || !e.shiftKey) return; if (e.altKey || e.ctrlKey || e.metaKey || !e.shiftKey) return;
if (e.keyCode === PERIOD_KEYCODE) changePlaybackSpeed(true); if (e.keyCode === PERIOD_KEYCODE) changePlaybackSpeed(true);
if (e.keyCode === COMMA_KEYCODE) changePlaybackSpeed(false); if (e.keyCode === COMMA_KEYCODE) changePlaybackSpeed(false);
if (e.keyCode === P_KEYCODE) setStartPlayPrevious(true);
if (e.keyCode === N_KEYCODE) setStartPlayNext(true); if (e.keyCode === N_KEYCODE) setStartPlayNext(true);
} }
@ -619,7 +623,8 @@ export default React.memo<Props>(function VideoJs(props: Props) {
player.children_[0].setAttribute('playsinline', ''); player.children_[0].setAttribute('playsinline', '');
// I think this is a callback function // I think this is a callback function
onPlayerReady(player); const videoNode = containerRef.current && containerRef.current.querySelector('video, audio');
onPlayerReady(player, videoNode);
}); });
// pre-roll ads // pre-roll ads

View file

@ -17,6 +17,7 @@ import FileViewerEmbeddedTitle from 'component/fileViewerEmbeddedTitle';
import LoadingScreen from 'component/common/loading-screen'; import LoadingScreen from 'component/common/loading-screen';
import { addTheaterModeButton } from './internal/theater-mode'; import { addTheaterModeButton } from './internal/theater-mode';
import { addPlayNextButton } from './internal/play-next'; import { addPlayNextButton } from './internal/play-next';
import { addPlayPreviousButton } from './internal/play-previous';
import { useGetAds } from 'effects/use-get-ads'; import { useGetAds } from 'effects/use-get-ads';
import Button from 'component/button'; import Button from 'component/button';
import I18nMessage from 'component/i18nMessage'; import I18nMessage from 'component/i18nMessage';
@ -54,6 +55,7 @@ type Props = {
doSetPlayingUri: (string, string) => void, doSetPlayingUri: (string, string) => void,
doPlayUri: (string) => void, doPlayUri: (string) => void,
playNextUri: string, playNextUri: string,
playPreviousUri: string,
authenticated: boolean, authenticated: boolean,
userId: number, userId: number,
homepageData?: { [string]: HomepageCat }, homepageData?: { [string]: HomepageCat },
@ -94,6 +96,7 @@ function VideoViewer(props: Props) {
doSetPlayingUri, doSetPlayingUri,
doPlayUri, doPlayUri,
playNextUri, playNextUri,
playPreviousUri,
homepageData, homepageData,
authenticated, authenticated,
userId, userId,
@ -126,6 +129,21 @@ function VideoViewer(props: Props) {
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [replay, setReplay] = useState(false); const [replay, setReplay] = useState(false);
const [startPlayNext, setStartPlayNext] = useState(false); const [startPlayNext, setStartPlayNext] = useState(false);
const [startPlayPrevious, setStartPlayPrevious] = useState(false);
const [videoNode, setVideoNode] = useState(false);
const getNavigateUrl = React.useCallback((playUri: string) => {
let navigateUrl;
if (playUri) {
navigateUrl = formatLbryUrlForWeb(playUri);
if (collectionId) {
const collectionParams = new URLSearchParams();
collectionParams.set(COLLECTIONS_CONSTS.COLLECTION_ID, collectionId);
navigateUrl = navigateUrl + `?` + collectionParams.toString();
}
}
return navigateUrl;
}, [collectionId]);
// force everything to recent when URI changes, can cause weird corner cases otherwise (e.g. navigate while autoplay is true) // force everything to recent when URI changes, can cause weird corner cases otherwise (e.g. navigate while autoplay is true)
useEffect(() => { useEffect(() => {
@ -144,18 +162,9 @@ function VideoViewer(props: Props) {
}; };
}, [embedded, videoPlaybackRate]); }, [embedded, videoPlaybackRate]);
let navigateUrl;
if (playNextUri) {
navigateUrl = formatLbryUrlForWeb(playNextUri);
if (collectionId) {
const collectionParams = new URLSearchParams();
collectionParams.set(COLLECTIONS_CONSTS.COLLECTION_ID, collectionId);
navigateUrl = navigateUrl + `?` + collectionParams.toString();
}
}
useEffect(() => { useEffect(() => {
if (startPlayNext) { if (startPlayNext) {
const navigateUrl = getNavigateUrl(playNextUri);
if (!isFloating && navigateUrl) { if (!isFloating && navigateUrl) {
push(navigateUrl); push(navigateUrl);
} }
@ -165,7 +174,26 @@ function VideoViewer(props: Props) {
} }
setStartPlayNext(false); setStartPlayNext(false);
} }
}, [isFloating, navigateUrl, push, doSetPlayingUri, playNextUri, doPlayUri, startPlayNext, collectionId]); if (videoNode) {
const currentTime = videoNode.currentTime;
if (startPlayPrevious) {
if (currentTime > 5) {
videoNode.currentTime = 0;
} else {
const navigateUrl = getNavigateUrl(playPreviousUri);
if (!isFloating && navigateUrl) {
push(navigateUrl);
}
if (playPreviousUri) {
doSetPlayingUri(playPreviousUri, collectionId);
doPlayUri(playPreviousUri);
}
}
setStartPlayPrevious(false);
}
}
}, [isFloating, push, doSetPlayingUri, playNextUri, doPlayUri, startPlayNext, collectionId, getNavigateUrl, videoNode, startPlayPrevious, playPreviousUri]);
function doTrackingBuffered(e: Event, data: any) { function doTrackingBuffered(e: Event, data: any) {
fetch(source, { method: 'HEAD', cache: 'no-store' }).then((response) => { fetch(source, { method: 'HEAD', cache: 'no-store' }).then((response) => {
@ -245,13 +273,17 @@ function VideoViewer(props: Props) {
playerReadyDependencyList.push(desktopPlayStartTime); playerReadyDependencyList.push(desktopPlayStartTime);
} }
const onPlayerReady = useCallback((player: Player) => { const onPlayerReady = useCallback((player: Player, videoNode: any) => {
if (!embedded) { if (!embedded) {
setVideoNode(videoNode);
player.muted(muted); player.muted(muted);
player.volume(volume); player.volume(volume);
player.playbackRate(videoPlaybackRate); player.playbackRate(videoPlaybackRate);
addTheaterModeButton(player, toggleVideoTheaterMode); addTheaterModeButton(player, toggleVideoTheaterMode);
if (collectionId) addPlayNextButton(player, () => setStartPlayNext(true)); if (collectionId) {
addPlayNextButton(player, () => setStartPlayNext(true));
addPlayPreviousButton(player, () => setStartPlayPrevious(true));
}
} }
const shouldPlay = !embedded || autoplayIfEmbedded; const shouldPlay = !embedded || autoplayIfEmbedded;
@ -382,6 +414,7 @@ function VideoViewer(props: Props) {
replay={replay} replay={replay}
videoTheaterMode={videoTheaterMode} videoTheaterMode={videoTheaterMode}
setStartPlayNext={setStartPlayNext} setStartPlayNext={setStartPlayNext}
setStartPlayPrevious={setStartPlayPrevious}
/> />
)} )}
</div> </div>