Media Viewer: Properly handle switching to PIP mode

This commit is contained in:
Alexander Zinchuk 2023-04-15 13:50:32 +02:00
parent 26ac63d49f
commit 01cf273b92
2 changed files with 18 additions and 7 deletions

View File

@ -33,7 +33,7 @@ import useFlag from '../../hooks/useFlag';
import useForceUpdate from '../../hooks/useForceUpdate';
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
import { dispatchPriorityPlaybackEvent } from '../../hooks/usePriorityPlaybackCheck';
import { exitPictureInPictureIfNeeded } from '../../hooks/usePictureInPicture';
import { exitPictureInPictureIfNeeded, usePictureInPictureSignal } from '../../hooks/usePictureInPicture';
import useLang from '../../hooks/useLang';
import usePrevious from '../../hooks/usePrevious';
import { useMediaProps } from './hooks/useMediaProps';
@ -144,8 +144,9 @@ const MediaViewer: FC<StateProps> = ({
animationKey.current = selectedMediaIndex;
}
const [getIsPictureInPicture] = usePictureInPictureSignal();
useEffect(() => {
if (!isOpen) {
if (!isOpen || getIsPictureInPicture()) {
return undefined;
}
@ -156,7 +157,7 @@ const MediaViewer: FC<StateProps> = ({
stopPriorityPlayback();
enableDirectTextInput();
};
}, [isOpen]);
}, [isOpen, getIsPictureInPicture]);
useEffect(() => {
if (isVisible) {

View File

@ -2,6 +2,7 @@ import { useLayoutEffect, useCallback, useState } from '../lib/teact/teact';
import { DEBUG } from '../config';
import { IS_IOS, IS_PWA } from '../util/windowEnvironment';
import safePlay, { getIsVideoPlaying } from '../util/safePlay';
import { createSignal } from '../util/signals';
type RefType = {
current: HTMLVideoElement | null;
@ -10,13 +11,20 @@ type RefType = {
type ReturnType = [boolean, () => void, boolean] | [false];
type CallbackType = () => void;
const signal = createSignal(false);
const setIsPictureInPicture = signal[1];
export function usePictureInPictureSignal() {
return signal;
}
export default function usePictureInPicture(
elRef: RefType,
onEnter: CallbackType,
onLeave: CallbackType,
): ReturnType {
const [isSupported, setIsSupported] = useState(false);
const [isInPictureInPicture, setIsInPictureInPicture] = useState(false);
const [isActive, setIsActive] = useState(false);
useLayoutEffect(() => {
// PIP is not supported in PWA on iOS, despite being detected
@ -31,11 +39,13 @@ export default function usePictureInPicture(
setIsSupported(true);
const onEnterInternal = () => {
onEnter();
setIsInPictureInPicture(true);
setIsActive(true);
setIsPictureInPicture(true);
};
const onLeaveInternal = () => {
setIsPictureInPicture(false);
setIsActive(false);
onLeave();
setIsInPictureInPicture(false);
};
video.addEventListener('enterpictureinpicture', onEnterInternal);
video.addEventListener('leavepictureinpicture', onLeaveInternal);
@ -77,7 +87,7 @@ export default function usePictureInPicture(
return [false];
}
return [isSupported, enterPictureInPicture, isInPictureInPicture];
return [isSupported, enterPictureInPicture, isActive];
}
function getSetPresentationMode(video: HTMLVideoElement) {