Skip to content

Commit c3b3527

Browse files
committed
Stop theme-irrelevant videos from loading
1 parent 235ae72 commit c3b3527

File tree

2 files changed

+67
-16
lines changed

2 files changed

+67
-16
lines changed
Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
'use client';
2+
3+
import * as React from "react";
4+
import { useTheme } from "next-themes";
5+
6+
import { useMounted } from '@/lib/hooks/use-mounted';
7+
18
import { StyledIframe } from "./video-player.styles";
29

310
const urlOptions = new URLSearchParams({
@@ -14,23 +21,47 @@ export const VideoPlayer = (props: {
1421
lightId: string,
1522
aspectRatio: string
1623
}) => {
24+
const { isMounted } = useMounted();
25+
const { resolvedTheme: theme } = useTheme();
26+
1727
const darkUrl = `https://iframe.mediadelivery.net/embed/${props.libraryId}/${props.darkId}?${urlOptions}`;
1828
const lightUrl = `https://iframe.mediadelivery.net/embed/${props.libraryId}/${props.lightId}?${urlOptions}`;
1929

30+
const darkVisibility = isMounted
31+
? theme === 'dark'
32+
: undefined;
33+
const lightVisibility = isMounted
34+
? theme === 'light'
35+
: undefined;
36+
2037
return <>
21-
<StyledIframe
22-
src={lightUrl}
23-
data-hide-on-theme="dark"
24-
aspectRatio={props.aspectRatio}
25-
allow="autoplay;picture-in-picture;"
26-
allowFullScreen={true}
27-
/>
28-
<StyledIframe
29-
src={darkUrl}
30-
data-hide-on-theme="light"
31-
aspectRatio={props.aspectRatio}
32-
allow="autoplay;picture-in-picture;"
33-
allowFullScreen={true}
34-
/>
38+
{ (!isMounted || theme === 'dark') &&
39+
<StyledIframe
40+
src={darkUrl}
41+
42+
loading="lazy"
43+
// Hide if wrong theme
44+
data-hide-on-theme="light"
45+
$visible={darkVisibility}
46+
47+
$aspectRatio={props.aspectRatio}
48+
allow="autoplay;picture-in-picture;"
49+
allowFullScreen={true}
50+
/>
51+
}
52+
{ (!isMounted || theme === 'light') &&
53+
<StyledIframe
54+
src={lightUrl}
55+
56+
loading="lazy"
57+
// Hide if wrong theme
58+
data-hide-on-theme="dark"
59+
$visible={lightVisibility}
60+
61+
$aspectRatio={props.aspectRatio}
62+
allow="autoplay;picture-in-picture;"
63+
allowFullScreen={true}
64+
/>
65+
}
3566
</>;
3667
};

src/components/elements/video-player/video-player.styles.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,29 @@
33
import { styled } from '@/styles';
44

55
export const StyledIframe = styled.iframe<{
6-
aspectRatio: string
6+
$aspectRatio: string,
7+
$visible: boolean | undefined
78
}>`
89
width: 100%;
9-
aspect-ratio: ${props => props.aspectRatio};
10+
aspect-ratio: ${props => props.$aspectRatio};
1011
border: none;
12+
13+
${p => p.$visible === undefined &&
14+
// During SSR, we render both and use CSS only to show the right default
15+
`
16+
@media (prefers-color-scheme: dark) {
17+
&[data-hide-on-theme="dark"] { display: none; }
18+
}
19+
20+
@media (prefers-color-scheme: light) {
21+
&[data-hide-on-theme="light"] { display: none; }
22+
}
23+
`}
24+
25+
${p => p.$visible === false &&
26+
// Once rendering is active, we render only the right one, but then we also
27+
// make it hidden until the content is actually ready.
28+
`
29+
visibility: hidden;
30+
`}
1131
`;

0 commit comments

Comments
 (0)