-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLazyVideoServer.tsx
More file actions
65 lines (55 loc) · 2.08 KB
/
LazyVideoServer.tsx
File metadata and controls
65 lines (55 loc) · 2.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import type { ReactNode } from "react";
import type { LazyVideoProps } from "../types/lazyVideoTypes";
import LazyVideoClient from "./LazyVideoClient";
// This wrapper function exists to take Function props and make them
// serializable for the LazyVideoClient component, which is a Next.js style
// client component.
export default function LazyVideo(props: LazyVideoProps): ReactNode {
// Destructure some props
const { src, sourceMedia, videoLoader } = props;
// Multiple media queries and a loader func are necessary for responsive
const useResponsiveSource =
sourceMedia && sourceMedia?.length > 1 && !!videoLoader;
// Vars that will be conditionally populated
let srcUrl, mediaSrcs;
// Prepare a hash of source URLs and their media query constraint in the
// style expected by useMediaQueries.
if (useResponsiveSource) {
const mediaSrcEntries = sourceMedia.map((media) => {
const url = videoLoader({ src, media });
return [url, media];
});
// If the array ended up empty, abort
if (mediaSrcEntries.filter(([url]) => !!url).length == 0) return null;
// Deduplicate entries to prevent conflicts when the same URL is returned
// for different media queries (e.g., same Contentful asset for portrait/landscape)
const deduplicatedEntries = mediaSrcEntries.reduce<[string, string][]>((acc, [url, media]) => {
if (!url || acc.some(([seenUrl]) => seenUrl === url)) {
return acc;
}
return [...acc, [url, media]];
}, []);
// Make the hash
mediaSrcs = Object.fromEntries(deduplicatedEntries);
// Make a simple string src url
} else {
if (videoLoader) srcUrl = videoLoader({ src });
else if (typeof src == "string") srcUrl = src;
if (!srcUrl) return null; // If no url could be built, abort
}
// Render client component
return (
<LazyVideoClient
{...{
...props,
// Remove client-unfriendly props
videoLoader: undefined,
src: undefined,
sourceMedia: undefined,
// Add client-friendly props
srcUrl,
mediaSrcs,
}}
/>
);
}