@vidstack/react
Version:
Build awesome media experiences on the web.
150 lines (141 loc) • 7.59 kB
JavaScript
import { createLiteReactElement, useReactContext } from 'maverick.js/react';
import { Outlet, Player, CommunitySkin, BufferingIndicator, CaptionButton, FullscreenButton, MuteButton, PIPButton, PlayButton, SeekButton, ToggleButton, Captions, Gesture, LiveIndicator, AudioMenuButton, AudioMenuItems, CaptionsMenuButton, CaptionsMenuItems, ChaptersMenuItems, MenuButton, MenuItems, Menu, PlaybackRateMenuButton, PlaybackRateMenuItems, QualityMenuButton, QualityMenuItems, RadioGroup, Radio, Poster, SliderThumbnail, SliderValue, SliderVideo, Slider, TimeSlider, VolumeSlider, Thumbnail, Time, Tooltip, mediaContext, MediaRemoteControl, MediaStoreFactory, SliderStoreFactory } from 'vidstack';
import { useState, useEffect, useMemo, useRef } from 'react';
import { effect, signal } from 'maverick.js';
import { isUndefined, isArray, noop } from 'maverick.js/std';
const MediaOutlet = /* @__PURE__ */ createLiteReactElement(Outlet);
const MediaPlayer = /* @__PURE__ */ createLiteReactElement(Player);
const MediaCommunitySkin = /* @__PURE__ */ createLiteReactElement(CommunitySkin);
const MediaBufferingIndicator = /* @__PURE__ */ createLiteReactElement(BufferingIndicator);
const MediaCaptionButton = /* @__PURE__ */ createLiteReactElement(CaptionButton);
const MediaFullscreenButton = /* @__PURE__ */ createLiteReactElement(FullscreenButton);
const MediaMuteButton = /* @__PURE__ */ createLiteReactElement(MuteButton);
const MediaPIPButton = /* @__PURE__ */ createLiteReactElement(PIPButton);
const MediaPlayButton = /* @__PURE__ */ createLiteReactElement(PlayButton);
const MediaSeekButton = /* @__PURE__ */ createLiteReactElement(SeekButton);
const MediaToggleButton = /* @__PURE__ */ createLiteReactElement(ToggleButton);
const MediaCaptions = /* @__PURE__ */ createLiteReactElement(Captions);
const MediaGesture = /* @__PURE__ */ createLiteReactElement(Gesture);
const MediaLiveIndicator = /* @__PURE__ */ createLiteReactElement(LiveIndicator);
const MediaAudioMenuButton = /* @__PURE__ */ createLiteReactElement(AudioMenuButton);
const MediaAudioMenuItems = /* @__PURE__ */ createLiteReactElement(AudioMenuItems);
const MediaCaptionsMenuButton = /* @__PURE__ */ createLiteReactElement(CaptionsMenuButton);
const MediaCaptionsMenuItems = /* @__PURE__ */ createLiteReactElement(CaptionsMenuItems);
const MediaChaptersMenuItems = /* @__PURE__ */ createLiteReactElement(ChaptersMenuItems);
const MediaMenuButton = /* @__PURE__ */ createLiteReactElement(MenuButton);
const MediaMenuItems = /* @__PURE__ */ createLiteReactElement(MenuItems);
const MediaMenu = /* @__PURE__ */ createLiteReactElement(Menu);
const MediaPlaybackRateMenuButton = /* @__PURE__ */ createLiteReactElement(PlaybackRateMenuButton);
const MediaPlaybackRateMenuItems = /* @__PURE__ */ createLiteReactElement(PlaybackRateMenuItems);
const MediaQualityMenuButton = /* @__PURE__ */ createLiteReactElement(QualityMenuButton);
const MediaQualityMenuItems = /* @__PURE__ */ createLiteReactElement(QualityMenuItems);
const MediaRadioGroup = /* @__PURE__ */ createLiteReactElement(RadioGroup);
const MediaRadio = /* @__PURE__ */ createLiteReactElement(Radio);
const MediaPoster = /* @__PURE__ */ createLiteReactElement(Poster);
const MediaSliderThumbnail = /* @__PURE__ */ createLiteReactElement(SliderThumbnail);
const MediaSliderValue = /* @__PURE__ */ createLiteReactElement(SliderValue);
const MediaSliderVideo = /* @__PURE__ */ createLiteReactElement(SliderVideo);
const MediaSlider = /* @__PURE__ */ createLiteReactElement(Slider);
const MediaTimeSlider = /* @__PURE__ */ createLiteReactElement(TimeSlider);
const MediaVolumeSlider = /* @__PURE__ */ createLiteReactElement(VolumeSlider);
const MediaThumbnail = /* @__PURE__ */ createLiteReactElement(Thumbnail);
const MediaTime = /* @__PURE__ */ createLiteReactElement(Time);
const MediaTooltip = /* @__PURE__ */ createLiteReactElement(Tooltip);
function useMediaPlayer() {
const [player, setPlayer] = useState(null), context = useReactContext(mediaContext);
if (!context) {
throw Error(
"[vidstack] no media context was found - was this called outside of `<MediaPlayer>`?"
);
}
useEffect(() => {
if (!context)
return;
setPlayer(context.player);
return () => setPlayer(null);
}, []);
return player;
}
function useMediaProvider() {
const [provider, setProvider] = useState(null), context = useReactContext(mediaContext);
if (!context) {
throw Error(
"[vidstack] no media context was found - was this called outside of `<MediaPlayer`?"
);
}
useEffect(() => {
if (!context)
return;
return effect(() => {
setProvider(context.$provider());
});
}, []);
return provider;
}
function useMediaRemote(target) {
const context = useReactContext(mediaContext), remote = useMemo(() => new MediaRemoteControl(), []);
useEffect(() => {
const player = context && context.player;
const ref = !isUndefined(target) ? target && "current" in target ? target.current : target : player;
remote.setTarget(ref || null);
remote.setPlayer(player || null);
}, [target]);
return remote;
}
function useStore(factory, ref, init) {
const [$store, $setStore] = useState(init), [_, update] = useState(0), tracking = useRef({
$props: signal([]),
observing: /* @__PURE__ */ new Set()
});
useEffect(() => {
const $store2 = ref?.current?.$store;
if ($store2)
$setStore($store2);
}, []);
useEffect(() => {
if (!$store)
return;
return effect(() => {
const props = tracking.current.$props();
for (let i = 0; i < props.length; i++)
$store[props[i]]();
update((n) => n + 1);
});
}, [$store]);
return useMemo(() => {
if (!$store)
return factory.record;
const { observing, $props } = tracking.current;
return new Proxy($store, {
get(_2, prop) {
if (!observing.has(prop)) {
$props.set((prev) => [...prev, prop]);
observing.add(prop);
}
const value = $store[prop]();
return isArray(value) ? [...value] : value;
},
// @ts-expect-error
set: noop
});
}, [$store]);
}
function useMediaStore(ref) {
const context = useReactContext(mediaContext);
if (!context && !ref) {
console.warn(
`[vidstack] \`useMediaStore\` requires \`RefObject<MediaPlayerElement>\` argument if called outside the <MediaPlayer> component`
);
}
return useStore(MediaStoreFactory, ref, context?.$store);
}
function useSliderStore(ref) {
const $store = useReactContext(SliderStoreFactory);
if (!$store && !ref) {
console.warn(
`[vidstack] \`useSliderStore\` requires \`RefObject<MediaSliderElement>\` argument if called outside a media slider component`
);
}
return useStore(SliderStoreFactory, ref, $store);
}
export { MediaAudioMenuButton, MediaAudioMenuItems, MediaBufferingIndicator, MediaCaptionButton, MediaCaptions, MediaCaptionsMenuButton, MediaCaptionsMenuItems, MediaChaptersMenuItems, MediaCommunitySkin, MediaFullscreenButton, MediaGesture, MediaLiveIndicator, MediaMenu, MediaMenuButton, MediaMenuItems, MediaMuteButton, MediaOutlet, MediaPIPButton, MediaPlayButton, MediaPlaybackRateMenuButton, MediaPlaybackRateMenuItems, MediaPlayer, MediaPoster, MediaQualityMenuButton, MediaQualityMenuItems, MediaRadio, MediaRadioGroup, MediaSeekButton, MediaSlider, MediaSliderThumbnail, MediaSliderValue, MediaSliderVideo, MediaThumbnail, MediaTime, MediaTimeSlider, MediaToggleButton, MediaTooltip, MediaVolumeSlider, useMediaPlayer, useMediaProvider, useMediaRemote, useMediaStore, useSliderStore };