mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
feat(react): setup react player api (#372)
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
'use client';
|
||||
|
||||
import type { Media } from '@videojs/core/dom';
|
||||
import type { UnknownState, UnknownStore } from '@videojs/store';
|
||||
import { useStore } from '@videojs/store/react';
|
||||
import type { Dispatch, HTMLAttributes, ReactNode, SetStateAction } from 'react';
|
||||
import { createContext, forwardRef, useContext, useEffect, useRef } from 'react';
|
||||
|
||||
import { useComposedRefs } from '../utils/use-composed-refs';
|
||||
|
||||
export interface PlayerContextValue {
|
||||
store: UnknownStore;
|
||||
media: Media | null;
|
||||
setMedia: Dispatch<SetStateAction<Media | null>>;
|
||||
}
|
||||
|
||||
const PlayerContext = createContext<PlayerContextValue | null>(null);
|
||||
|
||||
export function PlayerContextProvider({
|
||||
value,
|
||||
children,
|
||||
}: {
|
||||
value: PlayerContextValue;
|
||||
children: ReactNode;
|
||||
}): ReactNode {
|
||||
return <PlayerContext.Provider value={value}>{children}</PlayerContext.Provider>;
|
||||
}
|
||||
|
||||
export function usePlayerContext(): PlayerContextValue {
|
||||
const ctx = useContext(PlayerContext);
|
||||
if (!ctx) throw new Error('usePlayerContext must be used within a Player Provider');
|
||||
return ctx;
|
||||
}
|
||||
|
||||
export function usePlayer(): UnknownStore;
|
||||
export function usePlayer<R>(selector: (state: UnknownState) => R): R;
|
||||
export function usePlayer<R>(selector?: (state: UnknownState) => R) {
|
||||
const { store } = usePlayerContext();
|
||||
return useStore(store, selector as any);
|
||||
}
|
||||
|
||||
export function useMedia(): Media | null {
|
||||
const { media } = usePlayerContext();
|
||||
return media;
|
||||
}
|
||||
|
||||
export function useMediaRegistration(): Dispatch<SetStateAction<Media | null>> | undefined {
|
||||
const ctx = useContext(PlayerContext);
|
||||
return ctx?.setMedia;
|
||||
}
|
||||
|
||||
export interface ContainerProps extends HTMLAttributes<HTMLDivElement> {
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
export const Container = forwardRef<HTMLDivElement, ContainerProps>(function Container({ children, ...props }, ref) {
|
||||
const { store, media } = usePlayerContext();
|
||||
const internalRef = useRef<HTMLDivElement>(null);
|
||||
const composedRef = useComposedRefs(ref, internalRef);
|
||||
|
||||
useEffect(() => {
|
||||
if (!media) return;
|
||||
return store.attach({ media, container: internalRef.current });
|
||||
}, [media, store]);
|
||||
|
||||
return (
|
||||
<div ref={composedRef} {...props}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export namespace Container {
|
||||
export type Props = ContainerProps;
|
||||
}
|
||||
Reference in New Issue
Block a user