Commit 2ba023fc by Moorthy G

feat(responsive-video): check reduced motion preferences, ignore abortError on the video element

parent 5737bb9c
...@@ -14,6 +14,12 @@ export default meta; ...@@ -14,6 +14,12 @@ export default meta;
type Story = StoryObj<typeof meta>; type Story = StoryObj<typeof meta>;
const autoPlayFallback = (
<h3 className="font-bold text-lg text-light bg-primary px-4 py-2">
Auto play failed. I am a fallback element
</h3>
);
export const ResponsiveVideo: Story = { export const ResponsiveVideo: Story = {
args: { args: {
src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerFun.mp4', src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerFun.mp4',
...@@ -23,6 +29,7 @@ export const ResponsiveVideo: Story = { ...@@ -23,6 +29,7 @@ export const ResponsiveVideo: Story = {
media: '(min-width: 640px)' media: '(min-width: 640px)'
} }
], ],
autoPlayFallback,
autoPlay: true, autoPlay: true,
controls: true, controls: true,
muted: true muted: true
...@@ -33,10 +40,6 @@ export const AutoPlayFailed: Story = { ...@@ -33,10 +40,6 @@ export const AutoPlayFailed: Story = {
args: { args: {
src: 'broken.mp4', src: 'broken.mp4',
autoPlay: true, autoPlay: true,
autoPlayFallback: ( autoPlayFallback
<h3 className="font-bold text-lg text-light bg-primary px-4 py-2">
Auto play failed. I am a fallback element
</h3>
)
} }
}; };
...@@ -33,28 +33,52 @@ const ResponsiveVideo = ({ ...@@ -33,28 +33,52 @@ const ResponsiveVideo = ({
const videoRef = useRef<HTMLVideoElement>(null); const videoRef = useRef<HTMLVideoElement>(null);
useEffect(() => { useEffect(() => {
async function play() {
try {
autoPlay && (await videoRef?.current?.play());
} catch (err) {
setIsAutoPlayFailed(true);
}
}
play();
}, [autoPlay, currentSrc]);
useEffect(() => {
const handleResize = () => { const handleResize = () => {
/** find the set that matches current media query */
const matchedSet = srcSet?.find( const matchedSet = srcSet?.find(
({ media }) => window.matchMedia(breakpoints[media] || media).matches ({ media }) => window.matchMedia(breakpoints[media] || media).matches
); );
/* set the current src to the matched set or the default src */
setCurrentSrc(matchedSet?.src || src); setCurrentSrc(matchedSet?.src || src);
}; };
window.addEventListener('resize', handleResize); /* call handleResize on mount */
handleResize(); handleResize();
/* add resize event listener to window */
window.addEventListener('resize', handleResize);
/* remove event listener on unmount */
return () => window.removeEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize);
}, [src, srcSet]); }, [src, srcSet]);
useEffect(() => {
async function play() {
try {
/** If user prefers reduced motion,
* throw an error and stop autoplay
*/
const prefersReducedMotion = window.matchMedia(
'(prefers-reduced-motion: reduce)'
);
if (prefersReducedMotion.matches) {
throw new Error('User prefers reduced motion');
} else {
/* if autoplay is true, play the video */
autoPlay && (await videoRef?.current?.play());
}
} catch (error: any) {
/* AbortError happens when source is changed in runtime,
if error is not AbortError, mark autoPlay as failed
*/
if (error.name !== 'AbortError') {
console.error(error);
/* if play failed, report that autoplay has failed */
setIsAutoPlayFailed(true);
}
}
}
play();
}, [autoPlay, currentSrc]);
return isAutoPlayFailed && autoPlayFallback ? ( return isAutoPlayFailed && autoPlayFallback ? (
autoPlayFallback autoPlayFallback
) : ( ) : (
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment