Add Play Previous Button
This commit is contained in:
parent
73722a4f00
commit
bd64d5c9ea
3 changed files with 57 additions and 15 deletions
|
@ -6,6 +6,7 @@ import {
|
|||
SETTINGS,
|
||||
COLLECTIONS_CONSTS,
|
||||
makeSelectNextUrlForCollectionAndUrl,
|
||||
makeSelectPreviousUrlForCollectionAndUrl,
|
||||
} from 'lbry-redux';
|
||||
import { doChangeVolume, doChangeMute, doAnalyticsView, doAnalyticsBuffer } from 'redux/actions/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);
|
||||
|
||||
let playNextUri;
|
||||
let playPreviousUri;
|
||||
if (collectionId) {
|
||||
playNextUri = makeSelectNextUrlForCollectionAndUrl(collectionId, props.uri)(state);
|
||||
playPreviousUri = makeSelectPreviousUrlForCollectionAndUrl(collectionId, props.uri)(state);
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -55,6 +58,7 @@ const select = (state, props) => {
|
|||
isFloating: makeSelectIsPlayerFloating(props.location)(state),
|
||||
collectionId,
|
||||
playNextUri,
|
||||
playPreviousUri,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ type Props = {
|
|||
source: string,
|
||||
sourceType: string,
|
||||
poster: ?string,
|
||||
onPlayerReady: (Player) => void,
|
||||
onPlayerReady: (Player, any) => void,
|
||||
isAudio: boolean,
|
||||
startMuted: boolean,
|
||||
autoplay: boolean,
|
||||
|
@ -61,6 +61,7 @@ type Props = {
|
|||
shareTelemetry: boolean,
|
||||
replay: boolean,
|
||||
videoTheaterMode: boolean,
|
||||
setStartPlayPrevious: (boolean) => void,
|
||||
setStartPlayNext: (boolean) => void,
|
||||
};
|
||||
|
||||
|
@ -106,6 +107,7 @@ const SMALL_J_KEYCODE = 74;
|
|||
const SMALL_K_KEYCODE = 75;
|
||||
const SMALL_L_KEYCODE = 76;
|
||||
|
||||
const P_KEYCODE = 80;
|
||||
const N_KEYCODE = 78;
|
||||
|
||||
const ZERO_KEYCODE = 48;
|
||||
|
@ -215,6 +217,7 @@ export default React.memo<Props>(function VideoJs(props: Props) {
|
|||
shareTelemetry,
|
||||
replay,
|
||||
videoTheaterMode,
|
||||
setStartPlayPrevious,
|
||||
setStartPlayNext,
|
||||
} = 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.keyCode === PERIOD_KEYCODE) changePlaybackSpeed(true);
|
||||
if (e.keyCode === COMMA_KEYCODE) changePlaybackSpeed(false);
|
||||
if (e.keyCode === P_KEYCODE) setStartPlayPrevious(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', '');
|
||||
|
||||
// I think this is a callback function
|
||||
onPlayerReady(player);
|
||||
const videoNode = containerRef.current && containerRef.current.querySelector('video, audio');
|
||||
onPlayerReady(player, videoNode);
|
||||
});
|
||||
|
||||
// pre-roll ads
|
||||
|
|
|
@ -17,6 +17,7 @@ import FileViewerEmbeddedTitle from 'component/fileViewerEmbeddedTitle';
|
|||
import LoadingScreen from 'component/common/loading-screen';
|
||||
import { addTheaterModeButton } from './internal/theater-mode';
|
||||
import { addPlayNextButton } from './internal/play-next';
|
||||
import { addPlayPreviousButton } from './internal/play-previous';
|
||||
import { useGetAds } from 'effects/use-get-ads';
|
||||
import Button from 'component/button';
|
||||
import I18nMessage from 'component/i18nMessage';
|
||||
|
@ -54,6 +55,7 @@ type Props = {
|
|||
doSetPlayingUri: (string, string) => void,
|
||||
doPlayUri: (string) => void,
|
||||
playNextUri: string,
|
||||
playPreviousUri: string,
|
||||
authenticated: boolean,
|
||||
userId: number,
|
||||
homepageData?: { [string]: HomepageCat },
|
||||
|
@ -94,6 +96,7 @@ function VideoViewer(props: Props) {
|
|||
doSetPlayingUri,
|
||||
doPlayUri,
|
||||
playNextUri,
|
||||
playPreviousUri,
|
||||
homepageData,
|
||||
authenticated,
|
||||
userId,
|
||||
|
@ -126,6 +129,21 @@ function VideoViewer(props: Props) {
|
|||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [replay, setReplay] = 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)
|
||||
useEffect(() => {
|
||||
|
@ -144,18 +162,9 @@ function VideoViewer(props: Props) {
|
|||
};
|
||||
}, [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(() => {
|
||||
if (startPlayNext) {
|
||||
const navigateUrl = getNavigateUrl(playNextUri);
|
||||
if (!isFloating && navigateUrl) {
|
||||
push(navigateUrl);
|
||||
}
|
||||
|
@ -165,7 +174,26 @@ function VideoViewer(props: Props) {
|
|||
}
|
||||
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) {
|
||||
fetch(source, { method: 'HEAD', cache: 'no-store' }).then((response) => {
|
||||
|
@ -245,13 +273,17 @@ function VideoViewer(props: Props) {
|
|||
playerReadyDependencyList.push(desktopPlayStartTime);
|
||||
}
|
||||
|
||||
const onPlayerReady = useCallback((player: Player) => {
|
||||
const onPlayerReady = useCallback((player: Player, videoNode: any) => {
|
||||
if (!embedded) {
|
||||
setVideoNode(videoNode);
|
||||
player.muted(muted);
|
||||
player.volume(volume);
|
||||
player.playbackRate(videoPlaybackRate);
|
||||
addTheaterModeButton(player, toggleVideoTheaterMode);
|
||||
if (collectionId) addPlayNextButton(player, () => setStartPlayNext(true));
|
||||
if (collectionId) {
|
||||
addPlayNextButton(player, () => setStartPlayNext(true));
|
||||
addPlayPreviousButton(player, () => setStartPlayPrevious(true));
|
||||
}
|
||||
}
|
||||
|
||||
const shouldPlay = !embedded || autoplayIfEmbedded;
|
||||
|
@ -382,6 +414,7 @@ function VideoViewer(props: Props) {
|
|||
replay={replay}
|
||||
videoTheaterMode={videoTheaterMode}
|
||||
setStartPlayNext={setStartPlayNext}
|
||||
setStartPlayPrevious={setStartPlayPrevious}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue