UNPKG

@vidstack/react

Version:

Build awesome media experiences on the web.

150 lines (141 loc) 7.59 kB
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 };