import type { Context, ReactNode } from 'react'; import React, { createContext, useContext, useEffect, useMemo } from 'react'; import { AvailabilityStates, MediaUIEvents, MediaUIProps, StreamTypes, VolumeLevels, } from '../constants.js'; import createMediaStore, { type MediaState, type MediaStore, } from '../media-store/media-store.js'; import type { FullScreenElementStateOwner, MediaStateOwner, } from '../media-store/state-mediator.js'; import { useSyncExternalStoreWithSelector } from './useSyncExternalStoreWithSelector.js'; export * as timeUtils from '../utils/time.js'; /** * @description A lookup object for all well-defined action types that can be dispatched * to the `MediaStore`. As each action type name suggests, these all take the form of * "state change requests," where e.g. a component will `dispatch()` a request to change * some bit of media state, typically due to some user interaction. * * @example * import { useDispatch, MediaActionTypes } from 'media-chrome/react/media-store'; * * const MyComponent = () => { * const dispatch = useDispatch(); * return ( * * ); * }; * * @see {@link useMediaDispatch} */ export { MediaState }; export { AvailabilityStates, StreamTypes, VolumeLevels }; const { REGISTER_MEDIA_STATE_RECEIVER, // eslint-disable-line UNREGISTER_MEDIA_STATE_RECEIVER, // eslint-disable-line // NOTE: These generic state change requests are not currently supported (CJP) MEDIA_SHOW_TEXT_TRACKS_REQUEST, // eslint-disable-line MEDIA_HIDE_TEXT_TRACKS_REQUEST, // eslint-disable-line ...StateChangeRequests } = MediaUIEvents; export const MediaActionTypes = { ...StateChangeRequests, MEDIA_ELEMENT_CHANGE_REQUEST: 'mediaelementchangerequest', FULLSCREEN_ELEMENT_CHANGE_REQUEST: 'fullscreenelementchangerequest', } as const; export const MediaStateNames = { ...MediaUIProps } as const; const identity = (x?: any) => x; /** * @description The {@link https://react.dev/learn/passing-data-deeply-with-context#context-an-alternative-to-passing-props|React Context} * used "under the hood" for media ui state updates, state change requests, and the hooks and providers that integrate with this context. * It is unlikely that you will/should be using `MediaContext` directly. * * @see {@link MediaProvider} * @see {@link useMediaDispatch} * @see {@link useMediaSelector} */ export const MediaContext: Context = createContext(null); /** * @description A {@link https://react.dev/reference/react/createContext#provider|React Context.Provider} for having access * to media state and state updates. While many other react libraries that rely on `` and its corresponding context/hooks * are expected to have the context close to the top of the * {@link https://react.dev/learn/understanding-your-ui-as-a-tree#the-render-tree|React render tree}, `` should * typically be declared closer to the component (e.g. ``) level, as it manages the media state for a particular * playback experience (visual and otherwise), typically tightly tied to e.g. an `