mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
feat(core): add buffering indicator component (#527)
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
'use client';
|
||||
|
||||
import { BufferingIndicatorCore, BufferingIndicatorDataAttrs } from '@videojs/core';
|
||||
import { logMissingFeature, selectPlayback } from '@videojs/core/dom';
|
||||
import type { ForwardedRef } from 'react';
|
||||
import { forwardRef, useState, useSyncExternalStore } from 'react';
|
||||
|
||||
import { usePlayer } from '../../player/context';
|
||||
import type { UIComponentProps } from '../../utils/types';
|
||||
import { renderElement } from '../../utils/use-render';
|
||||
|
||||
export interface BufferingIndicatorProps
|
||||
extends UIComponentProps<'div', BufferingIndicatorCore.State>,
|
||||
BufferingIndicatorCore.Props {}
|
||||
|
||||
/**
|
||||
* Displays a buffering indicator when media is waiting for data.
|
||||
*
|
||||
* Visibility is delayed (default 500ms) to avoid flashing on quick buffers.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <BufferingIndicator />
|
||||
*
|
||||
* <BufferingIndicator delay={1000} />
|
||||
*
|
||||
* <BufferingIndicator
|
||||
* render={(props, state) => (
|
||||
* <div {...props}>{state.visible && <Spinner />}</div>
|
||||
* )}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export const BufferingIndicator = forwardRef(function BufferingIndicator(
|
||||
componentProps: BufferingIndicatorProps,
|
||||
forwardedRef: ForwardedRef<HTMLDivElement>
|
||||
) {
|
||||
const { render, className, style, delay, ...elementProps } = componentProps;
|
||||
|
||||
const playback = usePlayer(selectPlayback);
|
||||
|
||||
const [core] = useState(() => new BufferingIndicatorCore());
|
||||
core.setProps({ delay });
|
||||
|
||||
if (playback) core.update(playback);
|
||||
|
||||
const state = useSyncExternalStore(
|
||||
(cb) => core.state.subscribe(cb),
|
||||
() => core.state.current
|
||||
);
|
||||
|
||||
if (!playback) {
|
||||
if (__DEV__) logMissingFeature('BufferingIndicator', 'playback');
|
||||
return null;
|
||||
}
|
||||
|
||||
return renderElement(
|
||||
'div',
|
||||
{ render, className, style },
|
||||
{
|
||||
state,
|
||||
stateAttrMap: BufferingIndicatorDataAttrs,
|
||||
ref: [forwardedRef],
|
||||
props: [elementProps],
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
export namespace BufferingIndicator {
|
||||
export type Props = BufferingIndicatorProps;
|
||||
export type State = BufferingIndicatorCore.State;
|
||||
}
|
||||
Reference in New Issue
Block a user