Skip to content

Commit 75e89d9

Browse files
fix: Media controller insertBefore null (#575)
Co-authored-by: me <me@kentcdodds.com> Co-authored-by: Cursor Agent <cursoragent@cursor.com>
1 parent f8b8fd3 commit 75e89d9

1 file changed

Lines changed: 82 additions & 72 deletions

File tree

packages/workshop-app/app/components/epic-video.tsx

Lines changed: 82 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
} from 'media-chrome/react'
2121
import * as React from 'react'
2222
import { Await, Link, useFetcher, useRevalidator } from 'react-router'
23+
import { ClientOnly } from 'remix-utils/client-only'
2324
import { useEventSource } from 'remix-utils/sse/react'
2425
import { toast } from 'sonner'
2526
import { useTheme } from '#app/routes/theme/index.tsx'
@@ -758,84 +759,93 @@ function EpicVideo({
758759
onDelete={handleDelete}
759760
/>
760761
) : null
762+
const offlinePlayerFallback = (
763+
<div className="text-background flex h-full w-full items-center justify-center">
764+
<Loading>{title}</Loading>
765+
</div>
766+
)
761767
return (
762768
<div>
763769
<div className="shadow-lg">
764770
{shouldUseOfflineVideo ? (
765771
<div className="flex aspect-video w-full items-center justify-center bg-black">
766-
<MediaController
767-
tabIndex={0}
768-
aria-label={`${title} video player`}
769-
onPointerDown={(event) => {
770-
event.currentTarget.focus()
771-
}}
772-
className="focus-visible:ring-ring flex h-full w-full flex-col justify-end outline-none focus-visible:ring-2 focus-visible:ring-offset-2"
773-
style={
774-
{
775-
'--media-primary-color': 'hsl(var(--background))',
776-
'--media-text-color': 'hsl(var(--background))',
777-
'--media-secondary-color': 'transparent',
778-
'--media-control-background': 'transparent',
779-
'--media-control-hover-background':
780-
'hsl(var(--background) / 0.18)',
781-
'--media-control-height': '18px',
782-
'--media-range-padding': '2px',
783-
'--media-time-range-hover-height': '18px',
784-
'--media-time-range-hover-bottom': '-4px',
785-
'--media-range-track-height': '3px',
786-
'--media-range-thumb-height': '8px',
787-
'--media-range-thumb-width': '8px',
788-
'--media-range-track-background':
789-
'hsl(var(--background) / 0.35)',
790-
'--media-range-track-pointer-background':
791-
'hsl(var(--background) / 0.85)',
792-
} as React.CSSProperties
793-
}
794-
>
795-
<video
796-
ref={nativeVideoRef}
797-
slot="media"
798-
aria-label={title}
799-
className="h-full w-full"
800-
playsInline
801-
preload="metadata"
802-
src={offlineVideoUrl}
803-
onTimeUpdate={handleOfflineTimeUpdate}
804-
/>
805-
<div className="bg-foreground/40 text-background w-full space-y-1 px-3 pt-1 pb-1.5 text-sm leading-none backdrop-blur select-none">
806-
<MediaTimeRange className="w-full" />
807-
<MediaControlBar className="w-full items-center gap-3">
808-
<div className="flex items-center gap-3">
809-
<MediaPlayButton />
810-
<MediaSeekBackwardButton
811-
ref={setSeekOffset}
812-
seekOffset={10}
813-
/>
814-
<MediaSeekForwardButton
815-
ref={setSeekOffset}
816-
seekOffset={10}
817-
/>
818-
<MediaTimeDisplay
819-
showDuration
820-
className="text-background text-xs tabular-nums"
821-
/>
822-
<MediaMuteButton />
823-
<MediaVolumeRange className="w-24" />
772+
<ClientOnly fallback={offlinePlayerFallback}>
773+
{() => (
774+
<MediaController
775+
tabIndex={0}
776+
aria-label={`${title} video player`}
777+
onPointerDown={(event) => {
778+
event.currentTarget.focus()
779+
}}
780+
className="focus-visible:ring-ring flex h-full w-full flex-col justify-end outline-none focus-visible:ring-2 focus-visible:ring-offset-2"
781+
style={
782+
{
783+
'--media-primary-color': 'hsl(var(--background))',
784+
'--media-text-color': 'hsl(var(--background))',
785+
'--media-secondary-color': 'transparent',
786+
'--media-control-background': 'transparent',
787+
'--media-control-hover-background':
788+
'hsl(var(--background) / 0.18)',
789+
'--media-control-height': '18px',
790+
'--media-range-padding': '2px',
791+
'--media-time-range-hover-height': '18px',
792+
'--media-time-range-hover-bottom': '-4px',
793+
'--media-range-track-height': '3px',
794+
'--media-range-thumb-height': '8px',
795+
'--media-range-thumb-width': '8px',
796+
'--media-range-track-background':
797+
'hsl(var(--background) / 0.35)',
798+
'--media-range-track-pointer-background':
799+
'hsl(var(--background) / 0.85)',
800+
} as React.CSSProperties
801+
}
802+
>
803+
<video
804+
ref={nativeVideoRef}
805+
slot="media"
806+
aria-label={title}
807+
className="h-full w-full"
808+
playsInline
809+
preload="metadata"
810+
src={offlineVideoUrl}
811+
onTimeUpdate={handleOfflineTimeUpdate}
812+
/>
813+
<div className="bg-foreground/40 text-background w-full space-y-1 px-3 pt-1 pb-1.5 text-sm leading-none backdrop-blur select-none">
814+
<MediaTimeRange className="w-full" />
815+
<MediaControlBar className="w-full items-center gap-3">
816+
<div className="flex items-center gap-3">
817+
<MediaPlayButton />
818+
<MediaSeekBackwardButton
819+
ref={setSeekOffset}
820+
seekOffset={10}
821+
/>
822+
<MediaSeekForwardButton
823+
ref={setSeekOffset}
824+
seekOffset={10}
825+
/>
826+
<MediaTimeDisplay
827+
showDuration
828+
className="text-background text-xs tabular-nums"
829+
/>
830+
<MediaMuteButton />
831+
<MediaVolumeRange className="w-24" />
832+
</div>
833+
<div className="ml-auto flex items-center gap-3">
834+
<MediaPlaybackRateButton
835+
className="text-background text-xs"
836+
rates={[
837+
0.5, 0.75, 0.8, 0.9, 1, 1.25, 1.5, 1.75, 2, 2.5, 3,
838+
3.5, 4,
839+
]}
840+
/>
841+
<MediaPipButton />
842+
<MediaFullscreenButton />
843+
</div>
844+
</MediaControlBar>
824845
</div>
825-
<div className="ml-auto flex items-center gap-3">
826-
<MediaPlaybackRateButton
827-
className="text-background text-xs"
828-
rates={[
829-
0.5, 0.75, 0.8, 0.9, 1, 1.25, 1.5, 1.75, 2, 2.5, 3, 3.5,
830-
4,
831-
]}
832-
/>
833-
<MediaPipButton />
834-
<MediaFullscreenButton />
835-
</div>
836-
</MediaControlBar>
837-
</div>
838-
</MediaController>
846+
</MediaController>
847+
)}
848+
</ClientOnly>
839849
</div>
840850
) : !isOnline ? (
841851
<OfflineVideoUnavailable />

0 commit comments

Comments
 (0)