Media Viewer: Fix picture-in-picture mode breaking use of spaces (#221)

This commit is contained in:
Ibrahima G. Coulibaly 2023-01-22 17:18:49 +01:00 committed by GitHub
parent e15d569d7f
commit 9286889ea8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 8 deletions

View File

@ -92,6 +92,7 @@ const VideoPlayer: FC<OwnProps> = ({
const [
isPictureInPictureSupported,
enterPictureInPicture,
isInPictureInPicture,
] = usePictureInPicture(videoRef, handleEnterFullscreen, handleLeaveFullscreen);
const handleVideoMove = useCallback(() => {
@ -207,7 +208,7 @@ const VideoPlayer: FC<OwnProps> = ({
useEffect(() => {
if (!isMediaViewerOpen) return undefined;
const togglePayingStateBySpace = (e: KeyboardEvent) => {
if (e.key === 'Enter' || e.key === ' ') {
if ((e.key === 'Enter' || e.key === ' ') && !isInPictureInPicture) {
e.preventDefault();
togglePlayState(e);
}
@ -218,7 +219,7 @@ const VideoPlayer: FC<OwnProps> = ({
return () => {
document.removeEventListener('keydown', togglePayingStateBySpace, false);
};
}, [togglePlayState, isMediaViewerOpen]);
}, [togglePlayState, isMediaViewerOpen, isInPictureInPicture]);
const wrapperStyle = posterSize && `width: ${posterSize.width}px; height: ${posterSize.height}px`;
const videoStyle = `background-image: url(${posterData})`;

View File

@ -7,7 +7,7 @@ type RefType = {
current: HTMLVideoElement | null;
};
type ReturnType = [boolean, () => void] | [false];
type ReturnType = [boolean, () => void, boolean] | [false];
type CallbackType = () => void;
export default function usePictureInPicture(
@ -16,6 +16,7 @@ export default function usePictureInPicture(
onLeave: CallbackType,
): ReturnType {
const [isSupported, setIsSupported] = useState(false);
const [isInPictureInPicture, setIsInPictureInPicture] = useState(false);
useLayoutEffect(() => {
// PIP is not supported in PWA on iOS, despite being detected
@ -28,11 +29,19 @@ export default function usePictureInPicture(
// @ts-ignore
video.autoPictureInPicture = true;
setIsSupported(true);
video.addEventListener('enterpictureinpicture', onEnter);
video.addEventListener('leavepictureinpicture', onLeave);
const onEnterInternal = () => {
onEnter();
setIsInPictureInPicture(true);
};
const onLeaveInternal = () => {
onLeave();
setIsInPictureInPicture(false);
};
video.addEventListener('enterpictureinpicture', onEnterInternal);
video.addEventListener('leavepictureinpicture', onLeaveInternal);
return () => {
video.removeEventListener('enterpictureinpicture', onEnter);
video.removeEventListener('leavepictureinpicture', onLeave);
video.removeEventListener('enterpictureinpicture', onEnterInternal);
video.removeEventListener('leavepictureinpicture', onLeaveInternal);
};
}, [elRef, onEnter, onLeave]);
@ -68,7 +77,7 @@ export default function usePictureInPicture(
return [false];
}
return [isSupported, enterPictureInPicture];
return [isSupported, enterPictureInPicture, isInPictureInPicture];
}
function getSetPresentationMode(video: HTMLVideoElement) {