Files
v10/packages/react/src/ui/quality/use-quality-options.ts
T

92 lines
2.6 KiB
TypeScript

'use client';
import { QUALITY_AUTO_VALUE, QualityRadioGroupCore } from '@videojs/core';
import { logMissingFeature, selectQuality } from '@videojs/core/dom';
import { resolveTranslation, type Translator } from '@videojs/core/i18n';
import { useCallback, useState } from 'react';
import { useTranslator } from '../../i18n/context';
import { usePlayer } from '../../player/context';
export interface QualityOptionsProps extends QualityRadioGroupCore.Props {}
export interface QualityOption {
value: string;
label: string;
tier?: string | undefined;
badge?: string | undefined;
disabled: boolean;
}
export interface QualityOptionsResult {
state: QualityRadioGroupCore.State;
value: string;
options: QualityOption[];
disabled: boolean;
setValue: (value: string) => void;
}
const AUTO_LABEL_RE = /^Auto \((.+)\)$/;
function resolveAutoLabel(t: Translator, label: string): string {
const match = AUTO_LABEL_RE.exec(label);
if (match) {
return resolveTranslation(t, 'Auto ({label})', { label: match[1]! });
}
return resolveTranslation(t, label);
}
/**
* Create quality menu options (including an `Auto` option) from the player
* video rendition state. Returns `null` when the quality feature is not
* configured.
*
* @param props - Optional `label`, `formatRendition`, and `disabled` overrides.
*/
export function useQualityOptions(props?: QualityOptionsProps): QualityOptionsResult | null {
'use no memo';
const media = usePlayer(selectQuality);
const t = useTranslator();
const [core] = useState(() => new QualityRadioGroupCore());
core.setProps(props ?? {});
const setValue = useCallback((value: string) => core.selectValue(media!, value), [core, media]);
if (!media) {
if (__DEV__) logMissingFeature('useQualityOptions', selectQuality.displayName ?? 'quality');
return null;
}
core.setMedia(media);
const state = core.getState();
return {
state,
value: state.value,
options: [
{
value: QUALITY_AUTO_VALUE,
label: resolveAutoLabel(t, state.autoLabel),
disabled: state.disabled,
},
...state.renditions.map((rendition) => ({
value: rendition.value,
label: resolveTranslation(t, rendition.label),
...(rendition.tier && { tier: rendition.tier }),
...(rendition.badge && { badge: rendition.badge }),
disabled: state.disabled,
})),
],
disabled: state.disabled,
setValue,
};
}
export namespace useQualityOptions {
export type Props = QualityOptionsProps;
export type Result = QualityOptionsResult;
export type Option = QualityOption;
}