mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
feat(packages): add UI support for gestures and hotkeys (#1388)
Co-authored-by: Rahim <rahim.alwer@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Rahim
Claude Opus 4.6
parent
6c81f2d190
commit
0620814a67
@@ -1,3 +1,3 @@
|
||||
@import "../base.css";
|
||||
@import "../global.css";
|
||||
@import "../shared.css";
|
||||
@import "@videojs/skins/minimal/css/audio.css";
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
@import "../base.css";
|
||||
@import "../global.css";
|
||||
@import "../shared.css";
|
||||
@import "@videojs/skins/default/css/audio.css";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Base */
|
||||
/* Global styles for the host document, outside of the Shadow DOM */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
video-player,
|
||||
@@ -1,3 +1,3 @@
|
||||
@import "../base.css";
|
||||
@import "../global.css";
|
||||
@import "../shared.css";
|
||||
@import "@videojs/skins/minimal/css/audio.css";
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
@import "../base.css";
|
||||
@import "../global.css";
|
||||
@import "../shared.css";
|
||||
@import "@videojs/skins/default/css/audio.css";
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
@import "../base.css";
|
||||
@import "../global.css";
|
||||
@import "../shared.css";
|
||||
@import "@videojs/skins/minimal/css/video.css";
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
error,
|
||||
icon,
|
||||
iconState,
|
||||
inputFeedback,
|
||||
overlay,
|
||||
popup,
|
||||
poster,
|
||||
@@ -104,6 +105,54 @@ function getTemplateHTML() {
|
||||
</media-controls>
|
||||
|
||||
<div class="${overlay}"></div>
|
||||
|
||||
<!-- Hotkeys -->
|
||||
<media-hotkey keys="Space" action="togglePaused"></media-hotkey>
|
||||
<media-hotkey keys="k" action="togglePaused"></media-hotkey>
|
||||
<media-hotkey keys="m" action="toggleMuted"></media-hotkey>
|
||||
<media-hotkey keys="f" action="toggleFullscreen"></media-hotkey>
|
||||
<media-hotkey keys="c" action="toggleSubtitles"></media-hotkey>
|
||||
<media-hotkey keys="i" action="togglePictureInPicture"></media-hotkey>
|
||||
<media-hotkey keys="ArrowUp" action="volumeStep" value="0.05"></media-hotkey>
|
||||
<media-hotkey keys="ArrowDown" action="volumeStep" value="-0.05"></media-hotkey>
|
||||
|
||||
<!-- Gestures -->
|
||||
<media-gesture type="tap" action="togglePaused" pointer="mouse" region="center"></media-gesture>
|
||||
<media-gesture type="tap" action="toggleControls" pointer="touch"></media-gesture>
|
||||
<media-gesture type="doubletap" action="toggleFullscreen" region="center"></media-gesture>
|
||||
|
||||
<!-- Input Feedback -->
|
||||
<media-status-announcer></media-status-announcer>
|
||||
<div class="${inputFeedback.root}">
|
||||
<media-volume-indicator hidden class="${cn(inputFeedback.island.base, inputFeedback.island.volume, inputFeedback.island.shownVolume)}">
|
||||
<media-volume-indicator-fill data-feedback-island-content class="${inputFeedback.island.content}">
|
||||
${renderIcon('volume-high', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownVolumeHigh) })}
|
||||
${renderIcon('volume-low', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownVolumeLow) })}
|
||||
${renderIcon('volume-off', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownVolumeOff) })}
|
||||
<div aria-hidden="true" class="${inputFeedback.island.volumeProgress}"></div>
|
||||
<media-volume-indicator-value class="${inputFeedback.island.value}"></media-volume-indicator-value>
|
||||
</media-volume-indicator-fill>
|
||||
</media-volume-indicator>
|
||||
<media-status-indicator
|
||||
hidden
|
||||
actions="toggleSubtitles toggleFullscreen togglePictureInPicture"
|
||||
class="${cn(inputFeedback.island.base, inputFeedback.island.shownStatus)}"
|
||||
>
|
||||
<div class="${inputFeedback.island.content}">
|
||||
${renderIcon('captions-on', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownCaptionsOn) })}
|
||||
${renderIcon('captions-off', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownCaptionsOff) })}
|
||||
${renderIcon('fullscreen-enter', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownFullscreenEnter) })}
|
||||
${renderIcon('fullscreen-exit', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownFullscreenExit) })}
|
||||
${renderIcon('pip-enter', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownPipEnter) })}
|
||||
${renderIcon('pip-exit', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownPipExit) })}
|
||||
<media-status-indicator-value class="${inputFeedback.island.value}"></media-status-indicator-value>
|
||||
</div>
|
||||
</media-status-indicator>
|
||||
<media-status-indicator hidden actions="togglePaused" class="${inputFeedback.bubble.base}">
|
||||
${renderIcon('play', { class: cn(inputFeedback.bubble.icon, inputFeedback.bubble.shownPlay) })}
|
||||
${renderIcon('pause', { class: cn(inputFeedback.bubble.icon, inputFeedback.bubble.shownPause) })}
|
||||
</media-status-indicator>
|
||||
</div>
|
||||
</media-container>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -93,6 +93,54 @@ function getTemplateHTML() {
|
||||
</media-controls>
|
||||
|
||||
<div class="media-overlay"></div>
|
||||
|
||||
<!-- Hotkeys -->
|
||||
<media-hotkey keys="Space" action="togglePaused"></media-hotkey>
|
||||
<media-hotkey keys="k" action="togglePaused"></media-hotkey>
|
||||
<media-hotkey keys="m" action="toggleMuted"></media-hotkey>
|
||||
<media-hotkey keys="f" action="toggleFullscreen"></media-hotkey>
|
||||
<media-hotkey keys="c" action="toggleSubtitles"></media-hotkey>
|
||||
<media-hotkey keys="i" action="togglePictureInPicture"></media-hotkey>
|
||||
<media-hotkey keys="ArrowUp" action="volumeStep" value="0.05"></media-hotkey>
|
||||
<media-hotkey keys="ArrowDown" action="volumeStep" value="-0.05"></media-hotkey>
|
||||
|
||||
<!-- Gestures -->
|
||||
<media-gesture type="tap" action="togglePaused" pointer="mouse" region="center"></media-gesture>
|
||||
<media-gesture type="tap" action="toggleControls" pointer="touch"></media-gesture>
|
||||
<media-gesture type="doubletap" action="toggleFullscreen" region="center"></media-gesture>
|
||||
|
||||
<!-- Input Feedback -->
|
||||
<media-status-announcer></media-status-announcer>
|
||||
<div class="media-input-feedback">
|
||||
<media-volume-indicator hidden class="media-input-feedback-island media-input-feedback-island--volume">
|
||||
<media-volume-indicator-fill class="media-input-feedback-island__content">
|
||||
${renderIcon('volume-high', { class: 'media-icon media-icon--volume-high' })}
|
||||
${renderIcon('volume-low', { class: 'media-icon media-icon--volume-low' })}
|
||||
${renderIcon('volume-off', { class: 'media-icon media-icon--volume-off' })}
|
||||
<div class="media-input-feedback-island__progress" aria-hidden="true"></div>
|
||||
<media-volume-indicator-value class="media-input-feedback-island__value"></media-volume-indicator-value>
|
||||
</media-volume-indicator-fill>
|
||||
</media-volume-indicator>
|
||||
<media-status-indicator
|
||||
hidden
|
||||
actions="toggleSubtitles toggleFullscreen togglePictureInPicture"
|
||||
class="media-input-feedback-island media-input-feedback-island--status"
|
||||
>
|
||||
<div class="media-input-feedback-island__content">
|
||||
${renderIcon('captions-on', { class: 'media-icon media-icon--captions-on' })}
|
||||
${renderIcon('captions-off', { class: 'media-icon media-icon--captions-off' })}
|
||||
${renderIcon('fullscreen-enter', { class: 'media-icon media-icon--fullscreen-enter' })}
|
||||
${renderIcon('fullscreen-exit', { class: 'media-icon media-icon--fullscreen-exit' })}
|
||||
${renderIcon('pip-enter', { class: 'media-icon media-icon--pip-enter' })}
|
||||
${renderIcon('pip-exit', { class: 'media-icon media-icon--pip-exit' })}
|
||||
<media-status-indicator-value class="media-input-feedback-island__value"></media-status-indicator-value>
|
||||
</div>
|
||||
</media-status-indicator>
|
||||
<media-status-indicator hidden actions="togglePaused" class="media-input-feedback-bubble">
|
||||
${renderIcon('play', { class: 'media-icon media-icon--play' })}
|
||||
${renderIcon('pause', { class: 'media-icon media-icon--pause' })}
|
||||
</media-status-indicator>
|
||||
</div>
|
||||
</media-container>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import { BufferingIndicatorElement } from '../../ui/buffering-indicator/bufferin
|
||||
import { CaptionsButtonElement } from '../../ui/captions-button/captions-button-element';
|
||||
import { CastButtonElement } from '../../ui/cast-button/cast-button-element';
|
||||
import { FullscreenButtonElement } from '../../ui/fullscreen-button/fullscreen-button-element';
|
||||
import { GestureElement } from '../../ui/gesture/gesture-element';
|
||||
import { HotkeyElement } from '../../ui/hotkey/hotkey-element';
|
||||
import { LiveButtonElement } from '../../ui/live-button/live-button-element';
|
||||
import { MuteButtonElement } from '../../ui/mute-button/mute-button-element';
|
||||
import { PiPButtonElement } from '../../ui/pip-button/pip-button-element';
|
||||
@@ -16,7 +18,14 @@ import { PosterElement } from '../../ui/poster/poster-element';
|
||||
import { TooltipElement } from '../../ui/tooltip/tooltip-element';
|
||||
import { TooltipGroupElement } from '../../ui/tooltip/tooltip-group-element';
|
||||
import { safeDefine } from '../safe-define';
|
||||
import { defineControls, defineErrorDialog, defineTime, defineTimeSlider, defineVolumeSlider } from '../ui/compounds';
|
||||
import {
|
||||
defineControls,
|
||||
defineErrorDialog,
|
||||
defineInputIndicators,
|
||||
defineTime,
|
||||
defineTimeSlider,
|
||||
defineVolumeSlider,
|
||||
} from '../ui/compounds';
|
||||
|
||||
// Value import — player.ts body runs before this module's body.
|
||||
import { LiveVideoPlayerElement } from './player';
|
||||
@@ -29,6 +38,7 @@ safeDefine(MediaContainerElement);
|
||||
// Compound groups.
|
||||
defineControls();
|
||||
defineErrorDialog();
|
||||
defineInputIndicators();
|
||||
defineTimeSlider();
|
||||
defineVolumeSlider();
|
||||
defineTime();
|
||||
@@ -38,6 +48,8 @@ safeDefine(BufferingIndicatorElement);
|
||||
safeDefine(CaptionsButtonElement);
|
||||
safeDefine(CastButtonElement);
|
||||
safeDefine(FullscreenButtonElement);
|
||||
safeDefine(GestureElement);
|
||||
safeDefine(HotkeyElement);
|
||||
safeDefine(LiveButtonElement);
|
||||
safeDefine(MuteButtonElement);
|
||||
safeDefine(PiPButtonElement);
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
@import "../base.css";
|
||||
@import "../global.css";
|
||||
@import "../shared.css";
|
||||
@import "@videojs/skins/default/css/video.css";
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
error,
|
||||
icon,
|
||||
iconState,
|
||||
inputFeedback,
|
||||
overlay,
|
||||
popup,
|
||||
poster,
|
||||
@@ -106,6 +107,53 @@ function getTemplateHTML() {
|
||||
</media-controls>
|
||||
|
||||
<div class="${overlay}"></div>
|
||||
|
||||
<!-- Hotkeys -->
|
||||
<media-hotkey keys="Space" action="togglePaused"></media-hotkey>
|
||||
<media-hotkey keys="k" action="togglePaused"></media-hotkey>
|
||||
<media-hotkey keys="m" action="toggleMuted"></media-hotkey>
|
||||
<media-hotkey keys="f" action="toggleFullscreen"></media-hotkey>
|
||||
<media-hotkey keys="c" action="toggleSubtitles"></media-hotkey>
|
||||
<media-hotkey keys="i" action="togglePictureInPicture"></media-hotkey>
|
||||
<media-hotkey keys="ArrowUp" action="volumeStep" value="0.05"></media-hotkey>
|
||||
<media-hotkey keys="ArrowDown" action="volumeStep" value="-0.05"></media-hotkey>
|
||||
|
||||
<!-- Gestures -->
|
||||
<media-gesture type="tap" action="togglePaused" pointer="mouse" region="center"></media-gesture>
|
||||
<media-gesture type="tap" action="toggleControls" pointer="touch"></media-gesture>
|
||||
<media-gesture type="doubletap" action="toggleFullscreen" region="center"></media-gesture>
|
||||
|
||||
<!-- Input Feedback -->
|
||||
<media-status-announcer></media-status-announcer>
|
||||
<div class="${inputFeedback.root}">
|
||||
<media-volume-indicator hidden class="${cn(inputFeedback.island.base, inputFeedback.island.volume, inputFeedback.island.shownVolume)}">
|
||||
<media-volume-indicator-fill class="${inputFeedback.island.content}">
|
||||
${renderIcon('volume-high', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownVolumeHigh) })}
|
||||
${renderIcon('volume-low', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownVolumeLow) })}
|
||||
${renderIcon('volume-off', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownVolumeOff) })}
|
||||
<media-volume-indicator-value class="${inputFeedback.island.value}"></media-volume-indicator-value>
|
||||
</media-volume-indicator-fill>
|
||||
</media-volume-indicator>
|
||||
<media-status-indicator
|
||||
hidden
|
||||
actions="toggleSubtitles toggleFullscreen togglePictureInPicture"
|
||||
class="${cn(inputFeedback.island.base, inputFeedback.island.shownStatus)}"
|
||||
>
|
||||
<div class="${inputFeedback.island.content}">
|
||||
${renderIcon('captions-on', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownCaptionsOn) })}
|
||||
${renderIcon('captions-off', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownCaptionsOff) })}
|
||||
${renderIcon('fullscreen-enter', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownFullscreenEnter) })}
|
||||
${renderIcon('fullscreen-exit', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownFullscreenExit) })}
|
||||
${renderIcon('pip-enter', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownPipEnter) })}
|
||||
${renderIcon('pip-exit', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownPipExit) })}
|
||||
<media-status-indicator-value class="${inputFeedback.island.value}"></media-status-indicator-value>
|
||||
</div>
|
||||
</media-status-indicator>
|
||||
<media-status-indicator hidden actions="togglePaused" class="${inputFeedback.bubble.base}">
|
||||
${renderIcon('play', { class: cn(inputFeedback.bubble.icon, inputFeedback.bubble.shownPlay) })}
|
||||
${renderIcon('pause', { class: cn(inputFeedback.bubble.icon, inputFeedback.bubble.shownPause) })}
|
||||
</media-status-indicator>
|
||||
</div>
|
||||
</media-container>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -110,6 +110,38 @@ function getTemplateHTML() {
|
||||
<media-gesture type="tap" action="togglePaused" pointer="mouse" region="center"></media-gesture>
|
||||
<media-gesture type="tap" action="toggleControls" pointer="touch"></media-gesture>
|
||||
<media-gesture type="doubletap" action="toggleFullscreen" region="center"></media-gesture>
|
||||
|
||||
<!-- Input Feedback -->
|
||||
<media-status-announcer></media-status-announcer>
|
||||
<div class="media-input-feedback">
|
||||
<media-volume-indicator hidden class="media-surface media-input-feedback-island media-input-feedback-island--volume">
|
||||
<media-volume-indicator-fill class="media-input-feedback-island__content">
|
||||
${renderIcon('volume-high', { class: 'media-icon media-icon--volume-high' })}
|
||||
${renderIcon('volume-low', { class: 'media-icon media-icon--volume-low' })}
|
||||
${renderIcon('volume-off', { class: 'media-icon media-icon--volume-off' })}
|
||||
<media-volume-indicator-value class="media-input-feedback-island__value"></media-volume-indicator-value>
|
||||
</media-volume-indicator-fill>
|
||||
</media-volume-indicator>
|
||||
<media-status-indicator
|
||||
hidden
|
||||
actions="toggleSubtitles toggleFullscreen togglePictureInPicture"
|
||||
class="media-surface media-input-feedback-island media-input-feedback-island--status"
|
||||
>
|
||||
<div class="media-input-feedback-island__content">
|
||||
${renderIcon('captions-on', { class: 'media-icon media-icon--captions-on' })}
|
||||
${renderIcon('captions-off', { class: 'media-icon media-icon--captions-off' })}
|
||||
${renderIcon('fullscreen-enter', { class: 'media-icon media-icon--fullscreen-enter' })}
|
||||
${renderIcon('fullscreen-exit', { class: 'media-icon media-icon--fullscreen-exit' })}
|
||||
${renderIcon('pip-enter', { class: 'media-icon media-icon--pip-enter' })}
|
||||
${renderIcon('pip-exit', { class: 'media-icon media-icon--pip-exit' })}
|
||||
<media-status-indicator-value class="media-input-feedback-island__value"></media-status-indicator-value>
|
||||
</div>
|
||||
</media-status-indicator>
|
||||
<media-status-indicator hidden actions="togglePaused" class="media-input-feedback-bubble">
|
||||
${renderIcon('play', { class: 'media-icon media-icon--play' })}
|
||||
${renderIcon('pause', { class: 'media-icon media-icon--pause' })}
|
||||
</media-status-indicator>
|
||||
</div>
|
||||
</media-container>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,14 @@ import { PosterElement } from '../../ui/poster/poster-element';
|
||||
import { TooltipElement } from '../../ui/tooltip/tooltip-element';
|
||||
import { TooltipGroupElement } from '../../ui/tooltip/tooltip-group-element';
|
||||
import { safeDefine } from '../safe-define';
|
||||
import { defineControls, defineErrorDialog, defineTime, defineTimeSlider, defineVolumeSlider } from '../ui/compounds';
|
||||
import {
|
||||
defineControls,
|
||||
defineErrorDialog,
|
||||
defineInputIndicators,
|
||||
defineTime,
|
||||
defineTimeSlider,
|
||||
defineVolumeSlider,
|
||||
} from '../ui/compounds';
|
||||
|
||||
// Value import — player.ts body runs before this module's body.
|
||||
import { LiveVideoPlayerElement } from './player';
|
||||
@@ -30,6 +37,7 @@ safeDefine(MediaContainerElement);
|
||||
// Compound groups.
|
||||
defineControls();
|
||||
defineErrorDialog();
|
||||
defineInputIndicators();
|
||||
defineTimeSlider();
|
||||
defineVolumeSlider();
|
||||
defineTime();
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Shared styles for all HTML skins */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
media-tooltip-group {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
renderTemplate,
|
||||
type ShadowStyle,
|
||||
} from '@videojs/utils/dom';
|
||||
import rootStyles from './base.css?inline';
|
||||
import globalStyles from './global.css?inline';
|
||||
import sharedStyles from './shared.css?inline';
|
||||
|
||||
const STYLES_ID = '__media-styles';
|
||||
@@ -25,7 +25,7 @@ export class SkinElement extends ReactiveElement {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
ensureGlobalStyle(STYLES_ID, rootStyles);
|
||||
ensureGlobalStyle(STYLES_ID, globalStyles);
|
||||
|
||||
if (!this.shadowRoot) {
|
||||
const ctor = this.constructor as typeof SkinElement;
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
@import "@videojs/skins/shared/tailwind.css";
|
||||
@@ -4,6 +4,8 @@ import { AlertDialogTitleElement } from '../../ui/alert-dialog/alert-dialog-titl
|
||||
import { ControlsElement } from '../../ui/controls/controls-element';
|
||||
import { ControlsGroupElement } from '../../ui/controls/controls-group-element';
|
||||
import { ErrorDialogElement } from '../../ui/error-dialog/error-dialog-element';
|
||||
import { SeekIndicatorElement } from '../../ui/seek-indicator/seek-indicator-element';
|
||||
import { SeekIndicatorValueElement } from '../../ui/seek-indicator/seek-indicator-value-element';
|
||||
import { SliderBufferElement } from '../../ui/slider/slider-buffer-element';
|
||||
import { SliderElement } from '../../ui/slider/slider-element';
|
||||
import { SliderFillElement } from '../../ui/slider/slider-fill-element';
|
||||
@@ -12,10 +14,16 @@ import { SliderThumbElement } from '../../ui/slider/slider-thumb-element';
|
||||
import { SliderThumbnailElement } from '../../ui/slider/slider-thumbnail-element';
|
||||
import { SliderTrackElement } from '../../ui/slider/slider-track-element';
|
||||
import { SliderValueElement } from '../../ui/slider/slider-value-element';
|
||||
import { StatusAnnouncerElement } from '../../ui/status-announcer/status-announcer-element';
|
||||
import { StatusIndicatorElement } from '../../ui/status-indicator/status-indicator-element';
|
||||
import { StatusIndicatorValueElement } from '../../ui/status-indicator/status-indicator-value-element';
|
||||
import { TimeElement } from '../../ui/time/time-element';
|
||||
import { TimeGroupElement } from '../../ui/time/time-group-element';
|
||||
import { TimeSeparatorElement } from '../../ui/time/time-separator-element';
|
||||
import { TimeSliderElement } from '../../ui/time-slider/time-slider-element';
|
||||
import { VolumeIndicatorElement } from '../../ui/volume-indicator/volume-indicator-element';
|
||||
import { VolumeIndicatorFillElement } from '../../ui/volume-indicator/volume-indicator-fill-element';
|
||||
import { VolumeIndicatorValueElement } from '../../ui/volume-indicator/volume-indicator-value-element';
|
||||
import { VolumeSliderElement } from '../../ui/volume-slider/volume-slider-element';
|
||||
import { safeDefine } from '../safe-define';
|
||||
|
||||
@@ -34,6 +42,17 @@ export function defineErrorDialog(): void {
|
||||
safeDefine(AlertDialogTitleElement);
|
||||
}
|
||||
|
||||
export function defineInputIndicators(): void {
|
||||
safeDefine(StatusAnnouncerElement);
|
||||
safeDefine(StatusIndicatorElement);
|
||||
safeDefine(StatusIndicatorValueElement);
|
||||
safeDefine(VolumeIndicatorElement);
|
||||
safeDefine(VolumeIndicatorFillElement);
|
||||
safeDefine(VolumeIndicatorValueElement);
|
||||
safeDefine(SeekIndicatorElement);
|
||||
safeDefine(SeekIndicatorValueElement);
|
||||
}
|
||||
|
||||
/** Shared slider sub-elements used by all slider types. */
|
||||
export function defineSliderParts(): void {
|
||||
safeDefine(SliderFillElement);
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import { SeekIndicatorValueElement } from '../../ui/seek-indicator/seek-indicator-value-element';
|
||||
import { safeDefine } from '../safe-define';
|
||||
|
||||
safeDefine(SeekIndicatorValueElement);
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[SeekIndicatorValueElement.tagName]: SeekIndicatorValueElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { SeekIndicatorElement } from '../../ui/seek-indicator/seek-indicator-element';
|
||||
import { SeekIndicatorValueElement } from '../../ui/seek-indicator/seek-indicator-value-element';
|
||||
import { safeDefine } from '../safe-define';
|
||||
|
||||
safeDefine(SeekIndicatorElement);
|
||||
safeDefine(SeekIndicatorValueElement);
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[SeekIndicatorElement.tagName]: SeekIndicatorElement;
|
||||
[SeekIndicatorValueElement.tagName]: SeekIndicatorValueElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { StatusAnnouncerElement } from '../../ui/status-announcer/status-announcer-element';
|
||||
import { safeDefine } from '../safe-define';
|
||||
|
||||
safeDefine(StatusAnnouncerElement);
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[StatusAnnouncerElement.tagName]: StatusAnnouncerElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { StatusIndicatorValueElement } from '../../ui/status-indicator/status-indicator-value-element';
|
||||
import { safeDefine } from '../safe-define';
|
||||
|
||||
safeDefine(StatusIndicatorValueElement);
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[StatusIndicatorValueElement.tagName]: StatusIndicatorValueElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { StatusIndicatorElement } from '../../ui/status-indicator/status-indicator-element';
|
||||
import { StatusIndicatorValueElement } from '../../ui/status-indicator/status-indicator-value-element';
|
||||
import { safeDefine } from '../safe-define';
|
||||
|
||||
safeDefine(StatusIndicatorElement);
|
||||
safeDefine(StatusIndicatorValueElement);
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[StatusIndicatorElement.tagName]: StatusIndicatorElement;
|
||||
[StatusIndicatorValueElement.tagName]: StatusIndicatorValueElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { VolumeIndicatorFillElement } from '../../ui/volume-indicator/volume-indicator-fill-element';
|
||||
import { safeDefine } from '../safe-define';
|
||||
|
||||
safeDefine(VolumeIndicatorFillElement);
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[VolumeIndicatorFillElement.tagName]: VolumeIndicatorFillElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { VolumeIndicatorValueElement } from '../../ui/volume-indicator/volume-indicator-value-element';
|
||||
import { safeDefine } from '../safe-define';
|
||||
|
||||
safeDefine(VolumeIndicatorValueElement);
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[VolumeIndicatorValueElement.tagName]: VolumeIndicatorValueElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { VolumeIndicatorElement } from '../../ui/volume-indicator/volume-indicator-element';
|
||||
import { VolumeIndicatorFillElement } from '../../ui/volume-indicator/volume-indicator-fill-element';
|
||||
import { VolumeIndicatorValueElement } from '../../ui/volume-indicator/volume-indicator-value-element';
|
||||
import { safeDefine } from '../safe-define';
|
||||
|
||||
safeDefine(VolumeIndicatorElement);
|
||||
safeDefine(VolumeIndicatorFillElement);
|
||||
safeDefine(VolumeIndicatorValueElement);
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
[VolumeIndicatorElement.tagName]: VolumeIndicatorElement;
|
||||
[VolumeIndicatorFillElement.tagName]: VolumeIndicatorFillElement;
|
||||
[VolumeIndicatorValueElement.tagName]: VolumeIndicatorValueElement;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
@import "../base.css";
|
||||
@import "../global.css";
|
||||
@import "../shared.css";
|
||||
@import "@videojs/skins/minimal/css/video.css";
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
iconContainer,
|
||||
iconFlipped,
|
||||
iconState,
|
||||
inputFeedback,
|
||||
overlay,
|
||||
playbackRate,
|
||||
popup,
|
||||
@@ -152,6 +153,71 @@ function getTemplateHTML() {
|
||||
</media-controls>
|
||||
|
||||
<div class="${overlay}"></div>
|
||||
|
||||
<!-- Hotkeys -->
|
||||
<media-hotkey keys="Space" action="togglePaused"></media-hotkey>
|
||||
<media-hotkey keys="k" action="togglePaused"></media-hotkey>
|
||||
<media-hotkey keys="m" action="toggleMuted"></media-hotkey>
|
||||
<media-hotkey keys="f" action="toggleFullscreen"></media-hotkey>
|
||||
<media-hotkey keys="c" action="toggleSubtitles"></media-hotkey>
|
||||
<media-hotkey keys="i" action="togglePictureInPicture"></media-hotkey>
|
||||
<media-hotkey keys="ArrowRight" action="seekStep" value="5"></media-hotkey>
|
||||
<media-hotkey keys="ArrowLeft" action="seekStep" value="-5"></media-hotkey>
|
||||
<media-hotkey keys="l" action="seekStep" value="10"></media-hotkey>
|
||||
<media-hotkey keys="j" action="seekStep" value="-10"></media-hotkey>
|
||||
<media-hotkey keys="ArrowUp" action="volumeStep" value="0.05"></media-hotkey>
|
||||
<media-hotkey keys="ArrowDown" action="volumeStep" value="-0.05"></media-hotkey>
|
||||
<media-hotkey keys="0-9" action="seekToPercent"></media-hotkey>
|
||||
<media-hotkey keys="Home" action="seekToPercent" value="0"></media-hotkey>
|
||||
<media-hotkey keys="End" action="seekToPercent" value="100"></media-hotkey>
|
||||
<media-hotkey keys=">" action="speedUp"></media-hotkey>
|
||||
<media-hotkey keys="<" action="speedDown"></media-hotkey>
|
||||
|
||||
<!-- Gestures -->
|
||||
<media-gesture type="tap" action="togglePaused" pointer="mouse" region="center"></media-gesture>
|
||||
<media-gesture type="tap" action="toggleControls" pointer="touch"></media-gesture>
|
||||
<media-gesture type="doubletap" action="seekStep" value="-10" region="left"></media-gesture>
|
||||
<media-gesture type="doubletap" action="toggleFullscreen" region="center"></media-gesture>
|
||||
<media-gesture type="doubletap" action="seekStep" value="10" region="right"></media-gesture>
|
||||
|
||||
<!-- Input Feedback -->
|
||||
<media-status-announcer></media-status-announcer>
|
||||
<div class="${inputFeedback.root}">
|
||||
<media-volume-indicator
|
||||
hidden
|
||||
class="${cn(inputFeedback.island.base, inputFeedback.island.volume, inputFeedback.island.shownVolume)}"
|
||||
>
|
||||
<media-volume-indicator-fill data-feedback-island-content="" class="${inputFeedback.island.content}">
|
||||
${renderIcon('volume-high', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownVolumeHigh) })}
|
||||
${renderIcon('volume-low', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownVolumeLow) })}
|
||||
${renderIcon('volume-off', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownVolumeOff) })}
|
||||
<div aria-hidden="true" class="${inputFeedback.island.volumeProgress}"></div>
|
||||
<media-volume-indicator-value class="${inputFeedback.island.value}"></media-volume-indicator-value>
|
||||
</media-volume-indicator-fill>
|
||||
</media-volume-indicator>
|
||||
|
||||
<media-status-indicator hidden actions="toggleSubtitles toggleFullscreen togglePictureInPicture" class="${cn(inputFeedback.island.base, inputFeedback.island.shownStatus)}">
|
||||
<div class="${inputFeedback.island.content}">
|
||||
${renderIcon('captions-on', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownCaptionsOn) })}
|
||||
${renderIcon('captions-off', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownCaptionsOff) })}
|
||||
${renderIcon('fullscreen-enter', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownFullscreenEnter) })}
|
||||
${renderIcon('fullscreen-exit', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownFullscreenExit) })}
|
||||
${renderIcon('pip-enter', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownPipEnter) })}
|
||||
${renderIcon('pip-exit', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownPipExit) })}
|
||||
<media-status-indicator-value class="${inputFeedback.island.value}"></media-status-indicator-value>
|
||||
</div>
|
||||
</media-status-indicator>
|
||||
|
||||
<media-seek-indicator hidden class="${inputFeedback.bubble.base}">
|
||||
${renderIcon('chevron', { class: cn(inputFeedback.bubble.icon, inputFeedback.bubble.shownSeek) })}
|
||||
<media-seek-indicator-value class="${inputFeedback.bubble.time}"></media-seek-indicator-value>
|
||||
</media-seek-indicator>
|
||||
|
||||
<media-status-indicator hidden actions="togglePaused" class="${inputFeedback.bubble.base}">
|
||||
${renderIcon('play', { class: cn(inputFeedback.bubble.icon, inputFeedback.bubble.shownPlay) })}
|
||||
${renderIcon('pause', { class: cn(inputFeedback.bubble.icon, inputFeedback.bubble.shownPause) })}
|
||||
</media-status-indicator>
|
||||
</div>
|
||||
</media-container>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -134,6 +134,68 @@ function getTemplateHTML() {
|
||||
</media-controls>
|
||||
|
||||
<div class="media-overlay"></div>
|
||||
|
||||
<!-- Hotkeys -->
|
||||
<media-hotkey keys="Space" action="togglePaused"></media-hotkey>
|
||||
<media-hotkey keys="k" action="togglePaused"></media-hotkey>
|
||||
<media-hotkey keys="m" action="toggleMuted"></media-hotkey>
|
||||
<media-hotkey keys="f" action="toggleFullscreen"></media-hotkey>
|
||||
<media-hotkey keys="c" action="toggleSubtitles"></media-hotkey>
|
||||
<media-hotkey keys="i" action="togglePictureInPicture"></media-hotkey>
|
||||
<media-hotkey keys="ArrowRight" action="seekStep" value="5"></media-hotkey>
|
||||
<media-hotkey keys="ArrowLeft" action="seekStep" value="-5"></media-hotkey>
|
||||
<media-hotkey keys="l" action="seekStep" value="10"></media-hotkey>
|
||||
<media-hotkey keys="j" action="seekStep" value="-10"></media-hotkey>
|
||||
<media-hotkey keys="ArrowUp" action="volumeStep" value="0.05"></media-hotkey>
|
||||
<media-hotkey keys="ArrowDown" action="volumeStep" value="-0.05"></media-hotkey>
|
||||
<media-hotkey keys="0-9" action="seekToPercent"></media-hotkey>
|
||||
<media-hotkey keys="Home" action="seekToPercent" value="0"></media-hotkey>
|
||||
<media-hotkey keys="End" action="seekToPercent" value="100"></media-hotkey>
|
||||
<media-hotkey keys=">" action="speedUp"></media-hotkey>
|
||||
<media-hotkey keys="<" action="speedDown"></media-hotkey>
|
||||
|
||||
<!-- Gestures -->
|
||||
<media-gesture type="tap" action="togglePaused" pointer="mouse" region="center"></media-gesture>
|
||||
<media-gesture type="tap" action="toggleControls" pointer="touch"></media-gesture>
|
||||
<media-gesture type="doubletap" action="seekStep" value="-10" region="left"></media-gesture>
|
||||
<media-gesture type="doubletap" action="toggleFullscreen" region="center"></media-gesture>
|
||||
<media-gesture type="doubletap" action="seekStep" value="10" region="right"></media-gesture>
|
||||
|
||||
<!-- Input Feedback -->
|
||||
<media-status-announcer></media-status-announcer>
|
||||
<div class="media-input-feedback">
|
||||
<media-volume-indicator hidden class="media-input-feedback-island media-input-feedback-island--volume">
|
||||
<media-volume-indicator-fill class="media-input-feedback-island__content">
|
||||
${renderIcon('volume-high', { class: 'media-icon media-icon--volume-high' })}
|
||||
${renderIcon('volume-low', { class: 'media-icon media-icon--volume-low' })}
|
||||
${renderIcon('volume-off', { class: 'media-icon media-icon--volume-off' })}
|
||||
<div class="media-input-feedback-island__progress" aria-hidden="true"></div>
|
||||
<media-volume-indicator-value class="media-input-feedback-island__value"></media-volume-indicator-value>
|
||||
</media-volume-indicator-fill>
|
||||
</media-volume-indicator>
|
||||
|
||||
<media-status-indicator hidden actions="toggleSubtitles toggleFullscreen togglePictureInPicture" class="media-input-feedback-island media-input-feedback-island--status">
|
||||
<div class="media-input-feedback-island__content">
|
||||
${renderIcon('captions-on', { class: 'media-icon media-icon--captions-on' })}
|
||||
${renderIcon('captions-off', { class: 'media-icon media-icon--captions-off' })}
|
||||
${renderIcon('fullscreen-enter', { class: 'media-icon media-icon--fullscreen-enter' })}
|
||||
${renderIcon('fullscreen-exit', { class: 'media-icon media-icon--fullscreen-exit' })}
|
||||
${renderIcon('pip-enter', { class: 'media-icon media-icon--pip-enter' })}
|
||||
${renderIcon('pip-exit', { class: 'media-icon media-icon--pip-exit' })}
|
||||
<media-status-indicator-value class="media-input-feedback-island__value"></media-status-indicator-value>
|
||||
</div>
|
||||
</media-status-indicator>
|
||||
|
||||
<media-seek-indicator hidden class="media-input-feedback-bubble">
|
||||
${renderIcon('chevron', { class: 'media-icon media-icon--seek' })}
|
||||
<media-seek-indicator-value class="media-time"></media-seek-indicator-value>
|
||||
</media-seek-indicator>
|
||||
|
||||
<media-status-indicator hidden actions="togglePaused" class="media-input-feedback-bubble">
|
||||
${renderIcon('play', { class: 'media-icon media-icon--play' })}
|
||||
${renderIcon('pause', { class: 'media-icon media-icon--pause' })}
|
||||
</media-status-indicator>
|
||||
</div>
|
||||
</media-container>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import { BufferingIndicatorElement } from '../../ui/buffering-indicator/bufferin
|
||||
import { CaptionsButtonElement } from '../../ui/captions-button/captions-button-element';
|
||||
import { CastButtonElement } from '../../ui/cast-button/cast-button-element';
|
||||
import { FullscreenButtonElement } from '../../ui/fullscreen-button/fullscreen-button-element';
|
||||
import { GestureElement } from '../../ui/gesture/gesture-element';
|
||||
import { HotkeyElement } from '../../ui/hotkey/hotkey-element';
|
||||
import { MuteButtonElement } from '../../ui/mute-button/mute-button-element';
|
||||
import { PiPButtonElement } from '../../ui/pip-button/pip-button-element';
|
||||
import { PlayButtonElement } from '../../ui/play-button/play-button-element';
|
||||
@@ -16,7 +18,14 @@ import { SeekButtonElement } from '../../ui/seek-button/seek-button-element';
|
||||
import { TooltipElement } from '../../ui/tooltip/tooltip-element';
|
||||
import { TooltipGroupElement } from '../../ui/tooltip/tooltip-group-element';
|
||||
import { safeDefine } from '../safe-define';
|
||||
import { defineControls, defineErrorDialog, defineTime, defineTimeSlider, defineVolumeSlider } from '../ui/compounds';
|
||||
import {
|
||||
defineControls,
|
||||
defineErrorDialog,
|
||||
defineInputIndicators,
|
||||
defineTime,
|
||||
defineTimeSlider,
|
||||
defineVolumeSlider,
|
||||
} from '../ui/compounds';
|
||||
|
||||
// Value import — player.ts body runs before this module's body.
|
||||
import { VideoPlayerElement } from './player';
|
||||
@@ -29,6 +38,7 @@ safeDefine(MediaContainerElement);
|
||||
// Compound groups.
|
||||
defineControls();
|
||||
defineErrorDialog();
|
||||
defineInputIndicators();
|
||||
defineTimeSlider();
|
||||
defineVolumeSlider();
|
||||
defineTime();
|
||||
@@ -38,6 +48,8 @@ safeDefine(BufferingIndicatorElement);
|
||||
safeDefine(CaptionsButtonElement);
|
||||
safeDefine(CastButtonElement);
|
||||
safeDefine(FullscreenButtonElement);
|
||||
safeDefine(GestureElement);
|
||||
safeDefine(HotkeyElement);
|
||||
safeDefine(MuteButtonElement);
|
||||
safeDefine(PiPButtonElement);
|
||||
safeDefine(PlayButtonElement);
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
@import "../base.css";
|
||||
@import "../global.css";
|
||||
@import "../shared.css";
|
||||
@import "@videojs/skins/default/css/video.css";
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
iconContainer,
|
||||
iconFlipped,
|
||||
iconState,
|
||||
inputFeedback,
|
||||
overlay,
|
||||
playbackRate,
|
||||
popup,
|
||||
@@ -147,6 +148,70 @@ function getTemplateHTML() {
|
||||
</media-controls>
|
||||
|
||||
<div class="${overlay}"></div>
|
||||
|
||||
<!-- Hotkeys -->
|
||||
<media-hotkey keys="Space" action="togglePaused"></media-hotkey>
|
||||
<media-hotkey keys="k" action="togglePaused"></media-hotkey>
|
||||
<media-hotkey keys="m" action="toggleMuted"></media-hotkey>
|
||||
<media-hotkey keys="f" action="toggleFullscreen"></media-hotkey>
|
||||
<media-hotkey keys="c" action="toggleSubtitles"></media-hotkey>
|
||||
<media-hotkey keys="i" action="togglePictureInPicture"></media-hotkey>
|
||||
<media-hotkey keys="ArrowRight" action="seekStep" value="5"></media-hotkey>
|
||||
<media-hotkey keys="ArrowLeft" action="seekStep" value="-5"></media-hotkey>
|
||||
<media-hotkey keys="l" action="seekStep" value="10"></media-hotkey>
|
||||
<media-hotkey keys="j" action="seekStep" value="-10"></media-hotkey>
|
||||
<media-hotkey keys="ArrowUp" action="volumeStep" value="0.05"></media-hotkey>
|
||||
<media-hotkey keys="ArrowDown" action="volumeStep" value="-0.05"></media-hotkey>
|
||||
<media-hotkey keys="0-9" action="seekToPercent"></media-hotkey>
|
||||
<media-hotkey keys="Home" action="seekToPercent" value="0"></media-hotkey>
|
||||
<media-hotkey keys="End" action="seekToPercent" value="100"></media-hotkey>
|
||||
<media-hotkey keys=">" action="speedUp"></media-hotkey>
|
||||
<media-hotkey keys="<" action="speedDown"></media-hotkey>
|
||||
|
||||
<!-- Gestures -->
|
||||
<media-gesture type="tap" action="togglePaused" pointer="mouse" region="center"></media-gesture>
|
||||
<media-gesture type="tap" action="toggleControls" pointer="touch"></media-gesture>
|
||||
<media-gesture type="doubletap" action="seekStep" value="-10" region="left"></media-gesture>
|
||||
<media-gesture type="doubletap" action="toggleFullscreen" region="center"></media-gesture>
|
||||
<media-gesture type="doubletap" action="seekStep" value="10" region="right"></media-gesture>
|
||||
|
||||
<!-- Input Feedback -->
|
||||
<media-status-announcer></media-status-announcer>
|
||||
<div class="${inputFeedback.root}">
|
||||
<media-volume-indicator
|
||||
hidden
|
||||
class="${cn(inputFeedback.island.base, inputFeedback.island.volume, inputFeedback.island.shownVolume)}"
|
||||
>
|
||||
<media-volume-indicator-fill class="${inputFeedback.island.content}">
|
||||
${renderIcon('volume-high', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownVolumeHigh) })}
|
||||
${renderIcon('volume-low', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownVolumeLow) })}
|
||||
${renderIcon('volume-off', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownVolumeOff) })}
|
||||
<media-volume-indicator-value class="${inputFeedback.island.value}"></media-volume-indicator-value>
|
||||
</media-volume-indicator-fill>
|
||||
</media-volume-indicator>
|
||||
|
||||
<media-status-indicator hidden actions="toggleSubtitles toggleFullscreen togglePictureInPicture" class="${cn(inputFeedback.island.base, inputFeedback.island.shownStatus)}">
|
||||
<div class="${inputFeedback.island.content}">
|
||||
${renderIcon('captions-on', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownCaptionsOn) })}
|
||||
${renderIcon('captions-off', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownCaptionsOff) })}
|
||||
${renderIcon('fullscreen-enter', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownFullscreenEnter) })}
|
||||
${renderIcon('fullscreen-exit', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownFullscreenExit) })}
|
||||
${renderIcon('pip-enter', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownPipEnter) })}
|
||||
${renderIcon('pip-exit', { class: cn(inputFeedback.island.icon, inputFeedback.island.shownPipExit) })}
|
||||
<media-status-indicator-value class="${inputFeedback.island.value}"></media-status-indicator-value>
|
||||
</div>
|
||||
</media-status-indicator>
|
||||
|
||||
<media-seek-indicator hidden class="${inputFeedback.bubble.base}">
|
||||
${renderIcon('chevron', { class: cn(inputFeedback.bubble.icon, inputFeedback.bubble.shownSeek) })}
|
||||
<media-seek-indicator-value class="${inputFeedback.bubble.time}"></media-seek-indicator-value>
|
||||
</media-seek-indicator>
|
||||
|
||||
<media-status-indicator hidden actions="togglePaused" class="${inputFeedback.bubble.base}">
|
||||
${renderIcon('play', { class: cn(inputFeedback.bubble.icon, inputFeedback.bubble.shownPlay) })}
|
||||
${renderIcon('pause', { class: cn(inputFeedback.bubble.icon, inputFeedback.bubble.shownPause) })}
|
||||
</media-status-indicator>
|
||||
</div>
|
||||
</media-container>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -156,6 +156,42 @@ function getTemplateHTML() {
|
||||
<media-gesture type="doubletap" action="seekStep" value="-10" region="left"></media-gesture>
|
||||
<media-gesture type="doubletap" action="toggleFullscreen" region="center"></media-gesture>
|
||||
<media-gesture type="doubletap" action="seekStep" value="10" region="right"></media-gesture>
|
||||
|
||||
<!-- Input Feedback -->
|
||||
<media-status-announcer></media-status-announcer>
|
||||
<div class="media-input-feedback">
|
||||
<media-volume-indicator hidden class="media-surface media-input-feedback-island media-input-feedback-island--volume">
|
||||
<media-volume-indicator-fill class="media-input-feedback-island__content">
|
||||
${renderIcon('volume-high', { class: 'media-icon media-icon--volume-high' })}
|
||||
${renderIcon('volume-low', { class: 'media-icon media-icon--volume-low' })}
|
||||
${renderIcon('volume-off', { class: 'media-icon media-icon--volume-off' })}
|
||||
<media-volume-indicator-value class="media-input-feedback-island__value"></media-volume-indicator-value>
|
||||
</media-volume-indicator-fill>
|
||||
</media-volume-indicator>
|
||||
<media-status-indicator
|
||||
hidden
|
||||
actions="toggleSubtitles toggleFullscreen togglePictureInPicture"
|
||||
class="media-surface media-input-feedback-island media-input-feedback-island--status"
|
||||
>
|
||||
<div class="media-input-feedback-island__content">
|
||||
${renderIcon('captions-on', { class: 'media-icon media-icon--captions-on' })}
|
||||
${renderIcon('captions-off', { class: 'media-icon media-icon--captions-off' })}
|
||||
${renderIcon('fullscreen-enter', { class: 'media-icon media-icon--fullscreen-enter' })}
|
||||
${renderIcon('fullscreen-exit', { class: 'media-icon media-icon--fullscreen-exit' })}
|
||||
${renderIcon('pip-enter', { class: 'media-icon media-icon--pip-enter' })}
|
||||
${renderIcon('pip-exit', { class: 'media-icon media-icon--pip-exit' })}
|
||||
<media-status-indicator-value class="media-input-feedback-island__value"></media-status-indicator-value>
|
||||
</div>
|
||||
</media-status-indicator>
|
||||
<media-seek-indicator hidden class="media-input-feedback-bubble">
|
||||
${renderIcon('chevron', { class: 'media-icon media-icon--seek' })}
|
||||
<media-seek-indicator-value class="media-time"></media-seek-indicator-value>
|
||||
</media-seek-indicator>
|
||||
<media-status-indicator hidden actions="togglePaused" class="media-input-feedback-bubble">
|
||||
${renderIcon('play', { class: 'media-icon media-icon--play' })}
|
||||
${renderIcon('pause', { class: 'media-icon media-icon--pause' })}
|
||||
</media-status-indicator>
|
||||
</div>
|
||||
</media-container>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,14 @@ import { SeekButtonElement } from '../../ui/seek-button/seek-button-element';
|
||||
import { TooltipElement } from '../../ui/tooltip/tooltip-element';
|
||||
import { TooltipGroupElement } from '../../ui/tooltip/tooltip-group-element';
|
||||
import { safeDefine } from '../safe-define';
|
||||
import { defineControls, defineErrorDialog, defineTime, defineTimeSlider, defineVolumeSlider } from '../ui/compounds';
|
||||
import {
|
||||
defineControls,
|
||||
defineErrorDialog,
|
||||
defineInputIndicators,
|
||||
defineTime,
|
||||
defineTimeSlider,
|
||||
defineVolumeSlider,
|
||||
} from '../ui/compounds';
|
||||
|
||||
// Value import — player.ts body runs before this module's body.
|
||||
import { VideoPlayerElement } from './player';
|
||||
@@ -32,6 +39,7 @@ safeDefine(MediaContainerElement);
|
||||
// Compound groups.
|
||||
defineControls();
|
||||
defineErrorDialog();
|
||||
defineInputIndicators();
|
||||
defineTimeSlider();
|
||||
defineVolumeSlider();
|
||||
defineTime();
|
||||
|
||||
Reference in New Issue
Block a user