mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
327 lines
13 KiB
TypeScript
327 lines
13 KiB
TypeScript
// Generated by @videojs/compiler. Do not edit.
|
|
|
|
import {
|
|
airplayIcon,
|
|
bufferingIndicator,
|
|
button,
|
|
buttonGroupEnd,
|
|
buttonGroupStart,
|
|
castIcon,
|
|
container,
|
|
controls,
|
|
error,
|
|
fullscreenIcon,
|
|
icon,
|
|
iconFlipped,
|
|
inputFeedback,
|
|
overlay,
|
|
pipIcon,
|
|
playIcon,
|
|
popup,
|
|
poster as posterClass,
|
|
seek,
|
|
slider,
|
|
thumbnail,
|
|
time,
|
|
} from '@videojs/skins/default/tailwind/video.tailwind';
|
|
import { isString } from '@videojs/utils/predicate';
|
|
import { cn } from '@videojs/utils/style';
|
|
import type { ReactNode } from 'react';
|
|
import {
|
|
AirPlayEnterIcon,
|
|
AirPlayExitIcon,
|
|
CaptionsOffIcon,
|
|
CaptionsOnIcon,
|
|
CastEnterIcon,
|
|
CastExitIcon,
|
|
ChevronIcon,
|
|
FullscreenEnterIcon,
|
|
FullscreenExitIcon,
|
|
PauseIcon,
|
|
PipEnterIcon,
|
|
PipExitIcon,
|
|
PlayIcon,
|
|
RestartIcon,
|
|
SeekIcon,
|
|
SpinnerIcon,
|
|
VolumeHighIcon,
|
|
VolumeLowIcon,
|
|
VolumeOffIcon,
|
|
} from '@/icons';
|
|
import { Container } from '@/player/context';
|
|
import { AirPlayButton } from '@/ui/airplay-button';
|
|
import { BufferingIndicator } from '@/ui/buffering-indicator';
|
|
import { CastButton } from '@/ui/cast-button';
|
|
import { Controls } from '@/ui/controls';
|
|
import { ErrorDialog } from '@/ui/error-dialog';
|
|
import { FullscreenButton } from '@/ui/fullscreen-button';
|
|
import { Gesture } from '@/ui/gesture';
|
|
import { Hotkey } from '@/ui/hotkey';
|
|
import { Overlay } from '@/ui/overlay';
|
|
import { PiPButton } from '@/ui/pip-button';
|
|
import { PlayButton } from '@/ui/play-button';
|
|
import { Poster } from '@/ui/poster';
|
|
import { SeekButton } from '@/ui/seek-button';
|
|
import { SeekIndicator } from '@/ui/seek-indicator';
|
|
import { Slider } from '@/ui/slider';
|
|
import { StatusAnnouncer } from '@/ui/status-announcer';
|
|
import { StatusIndicator } from '@/ui/status-indicator';
|
|
import { Time } from '@/ui/time';
|
|
import { TimeSlider } from '@/ui/time-slider';
|
|
import { Tooltip } from '@/ui/tooltip';
|
|
import { VolumeIndicator } from '@/ui/volume-indicator';
|
|
import { isRenderProp } from '@/utils/use-render';
|
|
import type { BaseVideoSkinProps } from '../types';
|
|
|
|
const SEEK_TIME = 10;
|
|
|
|
const TOP_STATUS_ACTIONS = ['toggleSubtitles', 'toggleFullscreen', 'togglePictureInPicture'] as const;
|
|
|
|
const CENTER_STATUS_ACTIONS = ['togglePaused'] as const;
|
|
|
|
const iconButton = [button.base, button.subtle, button.icon];
|
|
|
|
export interface DefaultVideoSkinProps extends BaseVideoSkinProps {
|
|
className?: string;
|
|
children?: ReactNode | undefined;
|
|
}
|
|
|
|
export function DefaultVideoSkin({ className, children, poster, ...rest }: DefaultVideoSkinProps) {
|
|
return (
|
|
<Container className={cn(container, className)} {...rest}>
|
|
{children}
|
|
|
|
{poster && (
|
|
<Poster
|
|
src={isString(poster) ? poster : undefined}
|
|
render={isRenderProp(poster) ? poster : undefined}
|
|
className={posterClass}
|
|
/>
|
|
)}
|
|
|
|
<BufferingIndicator className={bufferingIndicator.root}>
|
|
<SpinnerIcon className={icon} />
|
|
</BufferingIndicator>
|
|
|
|
<ErrorDialog.Root>
|
|
<ErrorDialog.Popup className={error.popup}>
|
|
<ErrorDialog.Title className={error.title}>Something went wrong.</ErrorDialog.Title>
|
|
<ErrorDialog.Description className={error.description} />
|
|
<ErrorDialog.Close className={cn(button.base, button.primary, error.close)}>OK</ErrorDialog.Close>
|
|
</ErrorDialog.Popup>
|
|
</ErrorDialog.Root>
|
|
|
|
<Controls.Root className={controls} data-controls="">
|
|
<Tooltip.Provider>
|
|
<Controls.Group className={buttonGroupStart}>
|
|
<Tooltip.Root side="top">
|
|
<Tooltip.Trigger
|
|
render={
|
|
<PlayButton className={cn(iconButton, playIcon.button)} type="button">
|
|
<RestartIcon className={cn(icon, playIcon.restart)} />
|
|
<PlayIcon className={cn(icon, playIcon.play)} />
|
|
<PauseIcon className={cn(icon, playIcon.pause)} />
|
|
</PlayButton>
|
|
}
|
|
/>
|
|
<Tooltip.Popup className={popup.tooltip}>
|
|
<Tooltip.Label />
|
|
<Tooltip.Shortcut className={popup.tooltipShortcut} />
|
|
</Tooltip.Popup>
|
|
</Tooltip.Root>
|
|
|
|
<Tooltip.Root side="top">
|
|
<Tooltip.Trigger
|
|
render={
|
|
<SeekButton seconds={-SEEK_TIME} className={cn(iconButton, seek.button)} type="button">
|
|
<SeekIcon className={cn(icon, iconFlipped)} />
|
|
<span className={cn(seek.label, seek.labelBackward)}>{SEEK_TIME}</span>
|
|
</SeekButton>
|
|
}
|
|
/>
|
|
<Tooltip.Popup className={popup.tooltip}>
|
|
<Tooltip.Label />
|
|
<Tooltip.Shortcut className={popup.tooltipShortcut} />
|
|
</Tooltip.Popup>
|
|
</Tooltip.Root>
|
|
|
|
<Tooltip.Root side="top">
|
|
<Tooltip.Trigger
|
|
render={
|
|
<SeekButton seconds={SEEK_TIME} className={cn(iconButton, seek.button)} type="button">
|
|
<SeekIcon className={icon} />
|
|
<span className={cn(seek.label, seek.labelForward)}>{SEEK_TIME}</span>
|
|
</SeekButton>
|
|
}
|
|
/>
|
|
<Tooltip.Popup className={popup.tooltip}>
|
|
<Tooltip.Label />
|
|
<Tooltip.Shortcut className={popup.tooltipShortcut} />
|
|
</Tooltip.Popup>
|
|
</Tooltip.Root>
|
|
</Controls.Group>
|
|
|
|
<Time.Group className={time.group}>
|
|
<Time.Value type="current" className={time.current} />
|
|
<TimeSlider.Root className={slider.root}>
|
|
<TimeSlider.Track className={slider.track}>
|
|
<TimeSlider.Fill className={cn(slider.fill.base, slider.fill.fill)} />
|
|
<TimeSlider.Buffer className={cn(slider.fill.base, slider.fill.buffer)} />
|
|
</TimeSlider.Track>
|
|
<TimeSlider.Thumb className={cn(slider.thumb.base, slider.thumb.interactive)} />
|
|
<Slider.Thumbnail.Root className={thumbnail.root}>
|
|
<Slider.Thumbnail.Image className={thumbnail.image} />
|
|
<TimeSlider.Value type="pointer" className={thumbnail.time} />
|
|
<SpinnerIcon className={cn(icon, thumbnail.spinner)} />
|
|
</Slider.Thumbnail.Root>
|
|
<TimeSlider.Preview className={slider.preview}>
|
|
<TimeSlider.Value type="pointer" className={slider.value} />
|
|
</TimeSlider.Preview>
|
|
</TimeSlider.Root>
|
|
<Time.Value type="duration" className={time.duration} />
|
|
</Time.Group>
|
|
|
|
<Controls.Group className={buttonGroupEnd}>
|
|
<Tooltip.Root side="top">
|
|
<Tooltip.Trigger
|
|
render={
|
|
<CastButton className={cn(iconButton, castIcon.button)} type="button">
|
|
<CastEnterIcon className={cn(icon, castIcon.enter)} />
|
|
<CastExitIcon className={cn(icon, castIcon.exit)} />
|
|
</CastButton>
|
|
}
|
|
/>
|
|
<Tooltip.Popup className={popup.tooltip}>
|
|
<Tooltip.Label />
|
|
<Tooltip.Shortcut className={popup.tooltipShortcut} />
|
|
</Tooltip.Popup>
|
|
</Tooltip.Root>
|
|
|
|
<Tooltip.Root side="top">
|
|
<Tooltip.Trigger
|
|
render={
|
|
<AirPlayButton className={cn(iconButton, airplayIcon.button)} type="button">
|
|
<AirPlayEnterIcon className={cn(icon, airplayIcon.enter)} />
|
|
<AirPlayExitIcon className={cn(icon, airplayIcon.exit)} />
|
|
</AirPlayButton>
|
|
}
|
|
/>
|
|
<Tooltip.Popup className={popup.tooltip}>
|
|
<Tooltip.Label />
|
|
<Tooltip.Shortcut className={popup.tooltipShortcut} />
|
|
</Tooltip.Popup>
|
|
</Tooltip.Root>
|
|
|
|
<Tooltip.Root side="top">
|
|
<Tooltip.Trigger
|
|
render={
|
|
<PiPButton className={cn(iconButton, pipIcon.button)} type="button">
|
|
<PipEnterIcon className={cn(icon, pipIcon.off)} />
|
|
<PipExitIcon className={cn(icon, pipIcon.on)} />
|
|
</PiPButton>
|
|
}
|
|
/>
|
|
<Tooltip.Popup className={popup.tooltip}>
|
|
<Tooltip.Label />
|
|
<Tooltip.Shortcut className={popup.tooltipShortcut} />
|
|
</Tooltip.Popup>
|
|
</Tooltip.Root>
|
|
|
|
<Tooltip.Root side="top">
|
|
<Tooltip.Trigger
|
|
render={
|
|
<FullscreenButton className={cn(iconButton, fullscreenIcon.button)} type="button">
|
|
<FullscreenEnterIcon className={cn(icon, fullscreenIcon.enter)} />
|
|
<FullscreenExitIcon className={cn(icon, fullscreenIcon.exit)} />
|
|
</FullscreenButton>
|
|
}
|
|
/>
|
|
<Tooltip.Popup className={popup.tooltip}>
|
|
<Tooltip.Label />
|
|
<Tooltip.Shortcut className={popup.tooltipShortcut} />
|
|
</Tooltip.Popup>
|
|
</Tooltip.Root>
|
|
</Controls.Group>
|
|
</Tooltip.Provider>
|
|
</Controls.Root>
|
|
|
|
<Overlay className={overlay} />
|
|
|
|
<Hotkey keys="Space" action="togglePaused" />
|
|
<Hotkey keys="k" action="togglePaused" />
|
|
<Hotkey keys="m" action="toggleMuted" />
|
|
<Hotkey keys="f" action="toggleFullscreen" />
|
|
<Hotkey keys="c" action="toggleSubtitles" />
|
|
<Hotkey keys="i" action="togglePictureInPicture" />
|
|
<Hotkey keys="ArrowRight" action="seekStep" value={SEEK_TIME / 2} />
|
|
<Hotkey keys="ArrowLeft" action="seekStep" value={-(SEEK_TIME / 2)} />
|
|
<Hotkey keys="l" action="seekStep" value={SEEK_TIME} />
|
|
<Hotkey keys="j" action="seekStep" value={-SEEK_TIME} />
|
|
<Hotkey keys="ArrowUp" action="volumeStep" value={0.05} />
|
|
<Hotkey keys="ArrowDown" action="volumeStep" value={-0.05} />
|
|
<Hotkey keys="0-9" action="seekToPercent" />
|
|
<Hotkey keys="Home" action="seekToPercent" value={0} />
|
|
<Hotkey keys="End" action="seekToPercent" value={100} />
|
|
<Hotkey keys=">" action="speedUp" />
|
|
<Hotkey keys="<" action="speedDown" />
|
|
|
|
<Gesture type="tap" action="togglePaused" pointer="mouse" region="center" />
|
|
<Gesture type="tap" action="toggleControls" pointer="touch" />
|
|
<Gesture type="doubletap" action="seekStep" value={-SEEK_TIME} region="left" />
|
|
<Gesture type="doubletap" action="toggleFullscreen" region="center" />
|
|
<Gesture type="doubletap" action="seekStep" value={SEEK_TIME} region="right" />
|
|
|
|
<StatusAnnouncer />
|
|
|
|
<VolumeIndicator.Root
|
|
className={cn(
|
|
inputFeedback.island.root,
|
|
inputFeedback.island.base,
|
|
inputFeedback.island.volume,
|
|
inputFeedback.island.shownVolume
|
|
)}
|
|
>
|
|
<VolumeIndicator.Fill className={inputFeedback.island.content}>
|
|
<VolumeHighIcon className={cn(inputFeedback.island.icon, inputFeedback.island.shownVolumeHigh)} />
|
|
<VolumeLowIcon className={cn(inputFeedback.island.icon, inputFeedback.island.shownVolumeLow)} />
|
|
<VolumeOffIcon className={cn(inputFeedback.island.icon, inputFeedback.island.shownVolumeOff)} />
|
|
<VolumeIndicator.Value className={inputFeedback.island.value} />
|
|
</VolumeIndicator.Fill>
|
|
</VolumeIndicator.Root>
|
|
|
|
<StatusIndicator.Root
|
|
actions={TOP_STATUS_ACTIONS}
|
|
className={cn(
|
|
inputFeedback.island.root,
|
|
inputFeedback.island.base,
|
|
inputFeedback.island.statusContent,
|
|
inputFeedback.island.shownStatus
|
|
)}
|
|
>
|
|
<CaptionsOnIcon className={cn(inputFeedback.island.icon, inputFeedback.island.shownCaptionsOn)} />
|
|
<CaptionsOffIcon className={cn(inputFeedback.island.icon, inputFeedback.island.shownCaptionsOff)} />
|
|
<FullscreenEnterIcon className={cn(inputFeedback.island.icon, inputFeedback.island.shownFullscreenEnter)} />
|
|
<FullscreenExitIcon className={cn(inputFeedback.island.icon, inputFeedback.island.shownFullscreenExit)} />
|
|
<PipEnterIcon className={cn(inputFeedback.island.icon, inputFeedback.island.shownPipEnter)} />
|
|
<PipExitIcon className={cn(inputFeedback.island.icon, inputFeedback.island.shownPipExit)} />
|
|
<StatusIndicator.Value className={inputFeedback.island.value} />
|
|
</StatusIndicator.Root>
|
|
|
|
<SeekIndicator.Root
|
|
className={cn(inputFeedback.bubble.root, inputFeedback.bubble.seekRoot, inputFeedback.bubble.base)}
|
|
>
|
|
<ChevronIcon className={cn(inputFeedback.bubble.icon, inputFeedback.bubble.shownSeek)} />
|
|
<SeekIndicator.Value className={inputFeedback.bubble.time} />
|
|
</SeekIndicator.Root>
|
|
|
|
<StatusIndicator.Root
|
|
actions={CENTER_STATUS_ACTIONS}
|
|
className={cn(inputFeedback.bubble.root, inputFeedback.bubble.centerRoot, inputFeedback.bubble.base)}
|
|
>
|
|
<PlayIcon className={cn(inputFeedback.bubble.icon, inputFeedback.bubble.shownPlay)} />
|
|
<PauseIcon className={cn(inputFeedback.bubble.icon, inputFeedback.bubble.shownPause)} />
|
|
</StatusIndicator.Root>
|
|
</Container>
|
|
);
|
|
}
|