Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/contentful/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { defineConfig } from "cypress";

export default defineConfig({
browser: "chrome",
Comment thread
weotch marked this conversation as resolved.
Outdated
viewportWidth: 500,
viewportHeight: 500,
component: {
Expand Down
1 change: 1 addition & 0 deletions packages/next/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { defineConfig } from "cypress";

export default defineConfig({
browser: "chrome",
Comment thread
weotch marked this conversation as resolved.
Outdated
viewportWidth: 500,
viewportHeight: 500,
component: {
Expand Down
1 change: 1 addition & 0 deletions packages/react/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { defineConfig } from "cypress";

export default defineConfig({
browser: "chrome",
Comment thread
weotch marked this conversation as resolved.
Outdated
viewportWidth: 500,
viewportHeight: 500,
component: {
Expand Down
1 change: 0 additions & 1 deletion packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
"demo:build": "vite build --config vite.demo.config.ts"
},
"dependencies": {
"@react-hook/media-query": "^1.1.1",
"react-intersection-observer": "^9"
},
"peerDependencies": {
Expand Down
86 changes: 19 additions & 67 deletions packages/react/src/LazyVideo/LazyVideoClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@
"use client";

import { useInView } from "react-intersection-observer";
import { MediaQueryMatches, useMediaQueries } from "@react-hook/media-query";
import {
useEffect,
useRef,
useCallback,
type MutableRefObject,
useState,
type ReactNode,
useMemo,
} from "react";
import type { LazyVideoProps } from "../types/lazyVideoTypes";
import { fillStyles, transparentGif } from "../lib/styles";
Expand All @@ -30,11 +27,8 @@ type LazyVideoClientProps = Omit<

type ResponsiveVideoSourceProps = {
mediaSrcs: Required<LazyVideoClientProps>["mediaSrcs"];
videoRef: VideoRef;
};

type VideoRef = MutableRefObject<HTMLVideoElement | undefined>;

// An video rendered within a Visual that supports lazy loading
export default function LazyVideoClient({
srcUrl,
Expand Down Expand Up @@ -127,6 +121,17 @@ export default function LazyVideoClient({
};
}, []);

// Browsers won't swap <source media> on a video after initial load, so
// reload manually
useEffect(() => {
if (!mediaSrcs) return;
const queries = Object.keys(mediaSrcs).map((q) => window.matchMedia(q));
const reload = () => videoRef.current?.load();
queries.forEach((q) => q.addEventListener("change", reload));
return () =>
queries.forEach((q) => q.removeEventListener("change", reload));
}, [mediaSrcs]);

// Simplify logic for whether to load sources
const shouldLoad = priority || inView;

Expand Down Expand Up @@ -157,7 +162,14 @@ export default function LazyVideoClient({
{/* Implement lazy loading by not adding the source until ready */}
{shouldLoad &&
(mediaSrcs ? (
<ResponsiveSource {...{ mediaSrcs, videoRef }} />
Object.entries(mediaSrcs).map(([mediaQuery, src]) => (
<source
key={mediaQuery}
src={src}
type="video/mp4"
media={mediaQuery}
/>
))
) : (
<source src={srcUrl} type="video/mp4" />
))}
Expand All @@ -178,63 +190,3 @@ export default function LazyVideoClient({
</>
);
}

// Switch the video asset depending on media queries
function ResponsiveSource({
mediaSrcs,
videoRef,
}: ResponsiveVideoSourceProps): ReactNode {
// Make an object suitable for useMediaQueries that uses indexes from the
// mediaSrcs obj as its keys so there won't be any issues with multiple
// media queries using the same asset.
const indexedQueries = useMemo(() => {
return Object.keys(mediaSrcs).reduce<Record<number, string>>(
(queries, mediaQuery, index) => {
queries[index] = mediaQuery;
return queries;
},
{},
);
}, [mediaSrcs]);

// Find the src url that is currently active
const { matches } = useMediaQueries<typeof indexedQueries>(indexedQueries);
const srcUrl = getFirstMatch(mediaSrcs, matches);

// Reload the video since the source changed
useEffect(() => reloadVideoWhenSafe(videoRef), [matches]);

// Return new source
return <source src={srcUrl} type="video/mp4" />;
}

// Get the URL with a media query match
function getFirstMatch(
mediaSrcs: Record<string, string>,
matches: MediaQueryMatches<Record<number, string>>["matches"],
): string | undefined {
for (const index in matches) {
if (matches[index]) {
return Object.values(mediaSrcs)[index];
}
}
}

// Safely call load function on a video
function reloadVideoWhenSafe(videoRef: VideoRef): void {
if (!videoRef.current) return;
const video = videoRef.current;

// If already playing safely, load now
if (video.readyState >= 2) {
video.load();

// Else, wait for video to finish loading
} else {
const handleLoadedData = () => {
video.load();
video.removeEventListener("loadeddata", handleLoadedData);
};
video.addEventListener("loadeddata", handleLoadedData);
}
}
1 change: 1 addition & 0 deletions packages/sanity-next/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { defineConfig } from "cypress";

export default defineConfig({
browser: "chrome",
Comment thread
weotch marked this conversation as resolved.
Outdated
viewportWidth: 500,
viewportHeight: 500,

Expand Down
5 changes: 0 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -974,11 +974,6 @@
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==

"@react-hook/media-query@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@react-hook/media-query/-/media-query-1.1.1.tgz#7fc4e52591784a39be924b62b4270ae3e18ec578"
integrity sha512-VM14wDOX5CW5Dn6b2lTiMd79BFMTut9AZj2+vIRT3LCKgMCYmdqruTtzDPSnIVDQdtxdPgtOzvU9oK20LopuOw==

"@rollup/pluginutils@^5.1.0":
version "5.1.2"
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.2.tgz#d3bc9f0fea4fd4086aaac6aa102f3fa587ce8bd9"
Expand Down
Loading