Skip to content

Commit 3ce751e

Browse files
committed
main 🧊 add new hooks for video and audio
1 parent 63d6f8a commit 3ce751e

File tree

4 files changed

+58
-11
lines changed

4 files changed

+58
-11
lines changed

‎packages/core/src/bundle/hooks/usePictureInPicture/usePictureInPicture.js

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState } from 'react';
1+
import { useEffect, useRef, useState } from 'react';
22
import { getElement, isTarget } from '@/utils/helpers';
33
import { useRefState } from '../useRefState/useRefState';
44
/**
@@ -30,12 +30,14 @@ export const usePictureInPicture = (...params) => {
3030
const options = (target ? params[1] : params[0]) ?? {};
3131
const [open, setOpen] = useState(false);
3232
const internalRef = useRefState();
33+
const elementRef = useRef(null);
34+
const onOptionsRef = useRef(options);
35+
onOptionsRef.current = options;
3336
const supported = typeof document !== 'undefined' && 'pictureInPictureEnabled' in document;
3437
const enter = async () => {
3538
if (!supported) return;
36-
const element = target ? getElement(target) : internalRef.current;
37-
if (!element) return;
38-
await element.requestPictureInPicture();
39+
if (!elementRef.current) return;
40+
await elementRef.current.requestPictureInPicture();
3941
setOpen(true);
4042
options.onEnter?.();
4143
};
@@ -45,6 +47,25 @@ export const usePictureInPicture = (...params) => {
4547
setOpen(false);
4648
options.onExit?.();
4749
};
50+
useEffect(() => {
51+
const element = target ? getElement(target) : internalRef.current;
52+
if (!element) return;
53+
elementRef.current = element;
54+
const onEnterPictureInPicture = () => {
55+
setOpen(true);
56+
onOptionsRef.current.onEnter?.();
57+
};
58+
const onLeavePictureInPicture = () => {
59+
setOpen(false);
60+
onOptionsRef.current.onExit?.();
61+
};
62+
element.addEventListener('enterpictureinpicture', onEnterPictureInPicture);
63+
element.addEventListener('leavepictureinpicture', onLeavePictureInPicture);
64+
return () => {
65+
element.removeEventListener('enterpictureinpicture', onEnterPictureInPicture);
66+
element.removeEventListener('leavepictureinpicture', onLeavePictureInPicture);
67+
};
68+
}, [target]);
4869
const toggle = async () => {
4970
if (open) await exit();
5071
else await enter();

‎packages/core/src/bundle/hooks/useShallowEffect/useShallowEffect.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export const deepEqual = (a, b) => {
1818
};
1919
/**
2020
* @name useShallowEffect
21-
* @description - Hook that executes an effect only when dependencies change shallowly or deeply.
21+
* @description - Hook that executes an effect only when dependencies change shallowly or deeply
2222
* @category Lifecycle
2323
*
2424
* @param {EffectCallback} effect The effect callback

‎packages/core/src/hooks/usePictureInPicture/usePictureInPicture.ts

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState } from 'react';
1+
import { useEffect, useRef, useState } from 'react';
22

33
import type { HookTarget } from '@/utils/helpers';
44

@@ -69,17 +69,18 @@ export const usePictureInPicture = ((...params: any[]) => {
6969
const [open, setOpen] = useState(false);
7070

7171
const internalRef = useRefState<HTMLVideoElement>();
72+
const elementRef = useRef<HTMLVideoElement>(null);
73+
const onOptionsRef = useRef<UsePictureInPictureOptions>(options);
74+
onOptionsRef.current = options;
7275

7376
const supported = typeof document !== 'undefined' && 'pictureInPictureEnabled' in document;
7477

7578
const enter = async () => {
7679
if (!supported) return;
7780

78-
const element = target ? (getElement(target) as HTMLVideoElement) : internalRef.current;
79-
80-
if (!element) return;
81+
if (!elementRef.current) return;
8182

82-
await element.requestPictureInPicture();
83+
await elementRef.current.requestPictureInPicture();
8384
setOpen(true);
8485

8586
options.onEnter?.();
@@ -93,6 +94,31 @@ export const usePictureInPicture = ((...params: any[]) => {
9394
options.onExit?.();
9495
};
9596

97+
useEffect(() => {
98+
const element = target ? (getElement(target) as HTMLVideoElement) : internalRef.current;
99+
if (!element) return;
100+
101+
elementRef.current = element;
102+
103+
const onEnterPictureInPicture = () => {
104+
setOpen(true);
105+
onOptionsRef.current.onEnter?.();
106+
};
107+
108+
const onLeavePictureInPicture = () => {
109+
setOpen(false);
110+
onOptionsRef.current.onExit?.();
111+
};
112+
113+
element.addEventListener('enterpictureinpicture', onEnterPictureInPicture);
114+
element.addEventListener('leavepictureinpicture', onLeavePictureInPicture);
115+
116+
return () => {
117+
element.removeEventListener('enterpictureinpicture', onEnterPictureInPicture);
118+
element.removeEventListener('leavepictureinpicture', onLeavePictureInPicture);
119+
};
120+
}, [target]);
121+
96122
const toggle = async () => {
97123
if (open) await exit();
98124
else await enter();

‎packages/core/src/hooks/useShallowEffect/useShallowEffect.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const deepEqual = (a: any, b: any): boolean => {
2727

2828
/**
2929
* @name useShallowEffect
30-
* @description - Hook that executes an effect only when dependencies change shallowly or deeply.
30+
* @description - Hook that executes an effect only when dependencies change shallowly or deeply
3131
* @category Lifecycle
3232
*
3333
* @param {EffectCallback} effect The effect callback

0 commit comments

Comments
 (0)