Media Viewer: Properly handle switching to PIP mode
This commit is contained in:
parent
26ac63d49f
commit
01cf273b92
@ -33,7 +33,7 @@ import useFlag from '../../hooks/useFlag';
|
|||||||
import useForceUpdate from '../../hooks/useForceUpdate';
|
import useForceUpdate from '../../hooks/useForceUpdate';
|
||||||
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
import { dispatchHeavyAnimationEvent } from '../../hooks/useHeavyAnimationCheck';
|
||||||
import { dispatchPriorityPlaybackEvent } from '../../hooks/usePriorityPlaybackCheck';
|
import { dispatchPriorityPlaybackEvent } from '../../hooks/usePriorityPlaybackCheck';
|
||||||
import { exitPictureInPictureIfNeeded } from '../../hooks/usePictureInPicture';
|
import { exitPictureInPictureIfNeeded, usePictureInPictureSignal } from '../../hooks/usePictureInPicture';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
import usePrevious from '../../hooks/usePrevious';
|
import usePrevious from '../../hooks/usePrevious';
|
||||||
import { useMediaProps } from './hooks/useMediaProps';
|
import { useMediaProps } from './hooks/useMediaProps';
|
||||||
@ -144,8 +144,9 @@ const MediaViewer: FC<StateProps> = ({
|
|||||||
animationKey.current = selectedMediaIndex;
|
animationKey.current = selectedMediaIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const [getIsPictureInPicture] = usePictureInPictureSignal();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isOpen) {
|
if (!isOpen || getIsPictureInPicture()) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +157,7 @@ const MediaViewer: FC<StateProps> = ({
|
|||||||
stopPriorityPlayback();
|
stopPriorityPlayback();
|
||||||
enableDirectTextInput();
|
enableDirectTextInput();
|
||||||
};
|
};
|
||||||
}, [isOpen]);
|
}, [isOpen, getIsPictureInPicture]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { useLayoutEffect, useCallback, useState } from '../lib/teact/teact';
|
|||||||
import { DEBUG } from '../config';
|
import { DEBUG } from '../config';
|
||||||
import { IS_IOS, IS_PWA } from '../util/windowEnvironment';
|
import { IS_IOS, IS_PWA } from '../util/windowEnvironment';
|
||||||
import safePlay, { getIsVideoPlaying } from '../util/safePlay';
|
import safePlay, { getIsVideoPlaying } from '../util/safePlay';
|
||||||
|
import { createSignal } from '../util/signals';
|
||||||
|
|
||||||
type RefType = {
|
type RefType = {
|
||||||
current: HTMLVideoElement | null;
|
current: HTMLVideoElement | null;
|
||||||
@ -10,13 +11,20 @@ type RefType = {
|
|||||||
type ReturnType = [boolean, () => void, boolean] | [false];
|
type ReturnType = [boolean, () => void, boolean] | [false];
|
||||||
type CallbackType = () => void;
|
type CallbackType = () => void;
|
||||||
|
|
||||||
|
const signal = createSignal(false);
|
||||||
|
const setIsPictureInPicture = signal[1];
|
||||||
|
|
||||||
|
export function usePictureInPictureSignal() {
|
||||||
|
return signal;
|
||||||
|
}
|
||||||
|
|
||||||
export default function usePictureInPicture(
|
export default function usePictureInPicture(
|
||||||
elRef: RefType,
|
elRef: RefType,
|
||||||
onEnter: CallbackType,
|
onEnter: CallbackType,
|
||||||
onLeave: CallbackType,
|
onLeave: CallbackType,
|
||||||
): ReturnType {
|
): ReturnType {
|
||||||
const [isSupported, setIsSupported] = useState(false);
|
const [isSupported, setIsSupported] = useState(false);
|
||||||
const [isInPictureInPicture, setIsInPictureInPicture] = useState(false);
|
const [isActive, setIsActive] = useState(false);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
// PIP is not supported in PWA on iOS, despite being detected
|
// PIP is not supported in PWA on iOS, despite being detected
|
||||||
@ -31,11 +39,13 @@ export default function usePictureInPicture(
|
|||||||
setIsSupported(true);
|
setIsSupported(true);
|
||||||
const onEnterInternal = () => {
|
const onEnterInternal = () => {
|
||||||
onEnter();
|
onEnter();
|
||||||
setIsInPictureInPicture(true);
|
setIsActive(true);
|
||||||
|
setIsPictureInPicture(true);
|
||||||
};
|
};
|
||||||
const onLeaveInternal = () => {
|
const onLeaveInternal = () => {
|
||||||
|
setIsPictureInPicture(false);
|
||||||
|
setIsActive(false);
|
||||||
onLeave();
|
onLeave();
|
||||||
setIsInPictureInPicture(false);
|
|
||||||
};
|
};
|
||||||
video.addEventListener('enterpictureinpicture', onEnterInternal);
|
video.addEventListener('enterpictureinpicture', onEnterInternal);
|
||||||
video.addEventListener('leavepictureinpicture', onLeaveInternal);
|
video.addEventListener('leavepictureinpicture', onLeaveInternal);
|
||||||
@ -77,7 +87,7 @@ export default function usePictureInPicture(
|
|||||||
return [false];
|
return [false];
|
||||||
}
|
}
|
||||||
|
|
||||||
return [isSupported, enterPictureInPicture, isInPictureInPicture];
|
return [isSupported, enterPictureInPicture, isActive];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSetPresentationMode(video: HTMLVideoElement) {
|
function getSetPresentationMode(video: HTMLVideoElement) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user