Skip to content

Commit

Permalink
feat(player): expose cancellable media request events on all components
Browse files Browse the repository at this point in the history
  • Loading branch information
mihar-22 committed Jan 13, 2024
1 parent 3644a74 commit b6d84af
Show file tree
Hide file tree
Showing 30 changed files with 140 additions and 46 deletions.
4 changes: 2 additions & 2 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@
"media-captions": "^1.0.1"
},
"devDependencies": {
"@maverick-js/cli": "0.41.2",
"@maverick-js/cli": "0.41.3",
"@rollup/plugin-node-resolve": "^15.2.0",
"@types/fs-extra": "^11.0.1",
"@types/react": "^18.0.0",
"@vitejs/plugin-react": "^4.2.0",
"esbuild": "^0.19.4",
"fs-extra": "^11.0.0",
"maverick.js": "0.41.2",
"maverick.js": "0.41.3",
"media-icons": "^1.0.0",
"react": "^18.0.0",
"react-dom": "^18.0.0",
Expand Down
3 changes: 2 additions & 1 deletion packages/react/src/components/player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import { Primitive } from './primitives/nodes';

const MediaPlayerBridge = createReactComponent(MediaPlayerInstance, {
events: playerCallbacks,
eventsRegex: /^on(Hls|Media)/,
eventsRegex: /^onHls/,
domEventsRegex: /^onMedia/,
});

export interface MediaPlayerProps extends Omit<ReactElementProps<MediaPlayerInstance>, 'src'> {
Expand Down
4 changes: 3 additions & 1 deletion packages/react/src/components/ui/buttons/airplay-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import { Primitive } from '../../primitives/nodes';
* AirPlayButton
* -----------------------------------------------------------------------------------------------*/

const AirPlayButtonBridge = createReactComponent(AirPlayButtonInstance);
const AirPlayButtonBridge = createReactComponent(AirPlayButtonInstance, {
domEventsRegex: /^onMedia/,
});

export interface AirPlayButtonProps
extends ReactElementProps<AirPlayButtonInstance, HTMLButtonElement> {
Expand Down
4 changes: 3 additions & 1 deletion packages/react/src/components/ui/buttons/caption-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import { Primitive } from '../../primitives/nodes';
* CaptionButton
* -----------------------------------------------------------------------------------------------*/

const CaptionButtonBridge = createReactComponent(CaptionButtonInstance);
const CaptionButtonBridge = createReactComponent(CaptionButtonInstance, {
domEventsRegex: /^onMedia/,
});

export interface CaptionButtonProps
extends ReactElementProps<CaptionButtonInstance, HTMLButtonElement> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import { Primitive } from '../../primitives/nodes';
* FullscreenButton
* -----------------------------------------------------------------------------------------------*/

const FullscreenButtonBridge = createReactComponent(FullscreenButtonInstance);
const FullscreenButtonBridge = createReactComponent(FullscreenButtonInstance, {
domEventsRegex: /^onMedia/,
});

export interface FullscreenButtonProps
extends ReactElementProps<FullscreenButtonInstance, HTMLButtonElement> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import { Primitive } from '../../primitives/nodes';
* GoogleCastButton
* -----------------------------------------------------------------------------------------------*/

const GoogleCastButtonBridge = createReactComponent(GoogleCastButtonInstance);
const GoogleCastButtonBridge = createReactComponent(GoogleCastButtonInstance, {
domEventsRegex: /^onMedia/,
});

export interface GoogleCastButtonProps
extends ReactElementProps<GoogleCastButtonInstance, HTMLButtonElement> {
Expand Down
4 changes: 3 additions & 1 deletion packages/react/src/components/ui/buttons/live-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import { Primitive } from '../../primitives/nodes';
* LiveButton
* -----------------------------------------------------------------------------------------------*/

const LiveButtonBridge = createReactComponent(LiveButtonInstance);
const LiveButtonBridge = createReactComponent(LiveButtonInstance, {
domEventsRegex: /^onMedia/,
});

export interface LiveButtonProps extends ReactElementProps<LiveButtonInstance, HTMLButtonElement> {
asChild?: boolean;
Expand Down
4 changes: 3 additions & 1 deletion packages/react/src/components/ui/buttons/mute-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import { Primitive } from '../../primitives/nodes';
* MuteButton
* -----------------------------------------------------------------------------------------------*/

const MuteButtonBridge = createReactComponent(MuteButtonInstance);
const MuteButtonBridge = createReactComponent(MuteButtonInstance, {
domEventsRegex: /^onMedia/,
});

export interface MuteButtonProps extends ReactElementProps<MuteButtonInstance, HTMLButtonElement> {
asChild?: boolean;
Expand Down
4 changes: 3 additions & 1 deletion packages/react/src/components/ui/buttons/pip-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import { Primitive } from '../../primitives/nodes';
* PIPButton
* -----------------------------------------------------------------------------------------------*/

const PIPButtonBridge = createReactComponent(PIPButtonInstance);
const PIPButtonBridge = createReactComponent(PIPButtonInstance, {
domEventsRegex: /^onMedia/,
});

export interface PIPButtonProps extends ReactElementProps<PIPButtonInstance, HTMLButtonElement> {
asChild?: boolean;
Expand Down
4 changes: 3 additions & 1 deletion packages/react/src/components/ui/buttons/play-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import { Primitive } from '../../primitives/nodes';
* PlayButton
* -----------------------------------------------------------------------------------------------*/

const PlayButtonBridge = createReactComponent(PlayButtonInstance);
const PlayButtonBridge = createReactComponent(PlayButtonInstance, {
domEventsRegex: /^onMedia/,
});

export interface PlayButtonProps extends ReactElementProps<PlayButtonInstance, HTMLButtonElement> {
asChild?: boolean;
Expand Down
4 changes: 3 additions & 1 deletion packages/react/src/components/ui/buttons/seek-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import { Primitive } from '../../primitives/nodes';
* SeekButton
* -----------------------------------------------------------------------------------------------*/

const SeekButtonBridge = createReactComponent(SeekButtonInstance);
const SeekButtonBridge = createReactComponent(SeekButtonInstance, {
domEventsRegex: /^onMedia/,
});

export interface SeekButtonProps extends ReactElementProps<SeekButtonInstance, HTMLButtonElement> {
asChild?: boolean;
Expand Down
1 change: 1 addition & 0 deletions packages/react/src/components/ui/menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { Primitive } from '../primitives/nodes';

const MenuBridge = createReactComponent(MenuInstance, {
events: ['onOpen', 'onClose'],
domEventsRegex: /^onMedia/,
});

export interface RootProps extends ReactElementProps<MenuInstance> {
Expand Down
4 changes: 3 additions & 1 deletion packages/react/src/components/ui/sliders/time-slider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ TimeSliderContext.displayName = 'TimeSliderContext';
* TimeSlider
* -----------------------------------------------------------------------------------------------*/

const TimeSliderBridge = createReactComponent(TimeSliderInstance);
const TimeSliderBridge = createReactComponent(TimeSliderInstance, {
domEventsRegex: /^onMedia/,
});

export interface RootProps extends ReactElementProps<TimeSliderInstance> {
asChild?: boolean;
Expand Down
4 changes: 3 additions & 1 deletion packages/react/src/components/ui/sliders/volume-slider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ import { SliderValueBridge } from './slider-value';
* VolumeSlider
* -----------------------------------------------------------------------------------------------*/

const VolumeSliderBridge = createReactComponent(VolumeSliderInstance);
const VolumeSliderBridge = createReactComponent(VolumeSliderInstance, {
domEventsRegex: /^onMedia/,
});

export interface RootProps extends ReactElementProps<VolumeSliderInstance> {
asChild?: boolean;
Expand Down
4 changes: 2 additions & 2 deletions packages/vidstack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
},
"devDependencies": {
"@floating-ui/dom": "^1.4.4",
"@maverick-js/cli": "0.41.2",
"@maverick-js/cli": "0.41.3",
"@open-wc/semantic-dom-diff": "^0.20.0",
"@open-wc/testing-helpers": "^3.0.0",
"@rollup/plugin-node-resolve": "^15.2.0",
Expand All @@ -62,7 +62,7 @@
"just-debounce-it": "^3.2.0",
"just-throttle": "^4.2.0",
"lit-html": "^2.7.4",
"maverick.js": "0.41.2",
"maverick.js": "0.41.3",
"media-icons": "^1.0.0",
"postcss": "^8.4.0",
"rimraf": "^3.0.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Component } from 'maverick.js';

import { useMediaContext, type MediaContext } from '../../../core/api/media-context';
import type { MediaRequestEvents } from '../../../core/api/media-request-events';
import { $ariaBool } from '../../../utils/aria';
import { setARIALabel } from '../../../utils/dom';
import {
Expand All @@ -10,6 +11,8 @@ import {

export interface AirPlayButtonProps extends ToggleButtonControllerProps {}

export interface AirPlayButtonEvents extends Pick<MediaRequestEvents, 'media-airplay-request'> {}

/**
* A button for requesting Apple AirPlay.
*
Expand All @@ -19,7 +22,7 @@ export interface AirPlayButtonProps extends ToggleButtonControllerProps {}
* @see {@link https://www.apple.com/au/airplay}
* @docs {@link https://www.vidstack.io/docs/player/components/buttons/airplay-button}
*/
export class AirPlayButton extends Component<AirPlayButtonProps> {
export class AirPlayButton extends Component<AirPlayButtonProps, {}, AirPlayButtonEvents> {
static props: AirPlayButtonProps = ToggleButtonController.props;

private _media!: MediaContext;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Component } from 'maverick.js';

import { useMediaContext, type MediaContext } from '../../../core/api/media-context';
import type { MediaRequestEvents } from '../../../core/api/media-request-events';
import { isTrackCaptionKind } from '../../../core/tracks/text/text-track';
import { $ariaBool } from '../../../utils/aria';
import { setARIALabel } from '../../../utils/dom';
Expand All @@ -11,14 +12,17 @@ import {

export interface CaptionButtonProps extends ToggleButtonControllerProps {}

export interface CaptionButtonEvents
extends Pick<MediaRequestEvents, 'media-text-track-change-request'> {}

/**
* A button for toggling the showing state of the captions.
*
* @attr data-supported - Whether captions/subtitles are available.
* @attr data-active - Whether closed captions or subtitles are on.
* @docs {@link https://www.vidstack.io/docs/player/components/buttons/caption-button}
*/
export class CaptionButton extends Component<CaptionButtonProps> {
export class CaptionButton extends Component<CaptionButtonProps, {}, CaptionButtonEvents> {
static props: CaptionButtonProps = ToggleButtonController.props;

private _media!: MediaContext;
Expand Down
13 changes: 11 additions & 2 deletions packages/vidstack/src/components/ui/buttons/fullscreen-button.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { Component } from 'maverick.js';

import { useMediaContext, type MediaContext } from '../../../core/api/media-context';
import type { MediaFullscreenRequestTarget } from '../../../core/api/media-request-events';
import type {
MediaFullscreenRequestTarget,
MediaRequestEvents,
} from '../../../core/api/media-request-events';
import { $ariaBool } from '../../../utils/aria';
import { setARIALabel } from '../../../utils/dom';
import {
Expand All @@ -18,6 +21,12 @@ export interface FullscreenButtonProps extends ToggleButtonControllerProps {
target: MediaFullscreenRequestTarget | undefined;
}

export interface FullscreenButtonEvents
extends Pick<
MediaRequestEvents,
'media-enter-fullscreen-request' | 'media-exit-fullscreen-request'
> {}

/**
* A button for toggling the fullscreen mode of the player.
*
Expand All @@ -26,7 +35,7 @@ export interface FullscreenButtonProps extends ToggleButtonControllerProps {
* @docs {@link https://www.vidstack.io/docs/player/components/buttons/fullscreen-button}
* @see {@link https://www.vidstack.io/docs/player/core-concepts/fullscreen}
*/
export class FullscreenButton extends Component<FullscreenButtonProps> {
export class FullscreenButton extends Component<FullscreenButtonProps, {}, FullscreenButtonEvents> {
static props: FullscreenButtonProps = {
...ToggleButtonController.props,
target: 'prefer-media',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Component } from 'maverick.js';

import { useMediaContext, type MediaContext } from '../../../core/api/media-context';
import type { MediaRequestEvents } from '../../../core/api/media-request-events';
import { $ariaBool } from '../../../utils/aria';
import { setARIALabel } from '../../../utils/dom';
import {
Expand All @@ -10,6 +11,9 @@ import {

export interface GoogleCastButtonProps extends ToggleButtonControllerProps {}

export interface GoogleCastButtonEvents
extends Pick<MediaRequestEvents, 'media-google-cast-request'> {}

/**
* A button for requesting Google Cast.
*
Expand All @@ -19,7 +23,7 @@ export interface GoogleCastButtonProps extends ToggleButtonControllerProps {}
* @see {@link https://developers.google.com/cast/docs/overview}
* @docs {@link https://www.vidstack.io/docs/player/components/buttons/google-cast-button}
*/
export class GoogleCastButton extends Component<GoogleCastButtonProps> {
export class GoogleCastButton extends Component<GoogleCastButtonProps, {}, GoogleCastButtonEvents> {
static props: GoogleCastButtonProps = ToggleButtonController.props;

private _media!: MediaContext;
Expand Down
5 changes: 4 additions & 1 deletion packages/vidstack/src/components/ui/buttons/live-button.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Component } from 'maverick.js';

import { useMediaContext, type MediaContext } from '../../../core/api/media-context';
import type { MediaRequestEvents } from '../../../core/api/media-request-events';
import { FocusVisibleController } from '../../../foundation/observers/focus-visible';
import { $ariaBool } from '../../../utils/aria';
import { onPress, setAttributeIfEmpty } from '../../../utils/dom';
Expand All @@ -13,6 +14,8 @@ export interface LiveButtonProps {
disabled: boolean;
}

export interface LiveButtonEvents extends Pick<MediaRequestEvents, 'media-live-edge-request'> {}

/**
* This component displays the current live status of the stream. This includes whether it's
* live, at the live edge, or not live. In addition, when this button is pressed it will skip
Expand All @@ -24,7 +27,7 @@ export interface LiveButtonProps {
* @attr data-hocus - Whether button is being keyboard focused or hovered over.
* @docs {@link https://www.vidstack.io/docs/player/components/buttons/live-button}
*/
export class LiveButton extends Component<LiveButtonProps> {
export class LiveButton extends Component<LiveButtonProps, {}, LiveButtonEvents> {
static props: LiveButtonProps = {
disabled: false,
};
Expand Down
6 changes: 5 additions & 1 deletion packages/vidstack/src/components/ui/buttons/mute-button.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Component } from 'maverick.js';

import { useMediaContext, type MediaContext } from '../../../core/api/media-context';
import type { MediaRequestEvents } from '../../../core/api/media-request-events';
import { setARIALabel } from '../../../utils/dom';
import {
ToggleButtonController,
Expand All @@ -9,14 +10,17 @@ import {

export interface MuteButtonProps extends ToggleButtonControllerProps {}

export interface MuteButtonEvents
extends Pick<MediaRequestEvents, 'media-mute-request' | 'media-unmute-request'> {}

/**
* A button for toggling the muted state of the player.
*
* @attr data-muted - Whether volume is muted (0).
* @attr data-state - Current volume setting (low/high/muted).
* @docs {@link https://www.vidstack.io/docs/player/components/buttons/mute-button}
*/
export class MuteButton extends Component<MuteButtonProps> {
export class MuteButton extends Component<MuteButtonProps, {}, MuteButtonEvents> {
static props: MuteButtonProps = ToggleButtonController.props;

private _media!: MediaContext;
Expand Down
6 changes: 5 additions & 1 deletion packages/vidstack/src/components/ui/buttons/pip-button.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Component } from 'maverick.js';

import { useMediaContext, type MediaContext } from '../../../core/api/media-context';
import type { MediaRequestEvents } from '../../../core/api/media-request-events';
import { $ariaBool } from '../../../utils/aria';
import { setARIALabel } from '../../../utils/dom';
import {
Expand All @@ -10,6 +11,9 @@ import {

export interface PIPButtonProps extends ToggleButtonControllerProps {}

export interface PIPButtonEvents
extends Pick<MediaRequestEvents, 'media-enter-pip-request' | 'media-exit-pip-request'> {}

/**
* A button for toggling the picture-in-picture (PIP) mode of the player.
*
Expand All @@ -18,7 +22,7 @@ export interface PIPButtonProps extends ToggleButtonControllerProps {}
* @docs {@link https://www.vidstack.io/docs/player/components/buttons/pip-button}
* @see {@link https://www.vidstack.io/docs/player/core-concepts/picture-in-picture}
*/
export class PIPButton extends Component<PIPButtonProps> {
export class PIPButton extends Component<PIPButtonProps, {}, PIPButtonEvents> {
static props: PIPButtonProps = ToggleButtonController.props;

private _media!: MediaContext;
Expand Down
6 changes: 5 additions & 1 deletion packages/vidstack/src/components/ui/buttons/play-button.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Component } from 'maverick.js';

import { useMediaContext, type MediaContext } from '../../../core/api/media-context';
import type { MediaRequestEvents } from '../../../core/api/media-request-events';
import { setARIALabel } from '../../../utils/dom';
import {
ToggleButtonController,
Expand All @@ -9,14 +10,17 @@ import {

export interface PlayButtonProps extends ToggleButtonControllerProps {}

export interface PlayButtonEvents
extends Pick<MediaRequestEvents, 'media-play-request' | 'media-pause-request'> {}

/**
* A button for toggling the playback state (play/pause) of the current media.
*
* @attr data-paused - Whether playback has stopped.
* @attr data-ended - Whether playback has ended.
* @docs {@link https://www.vidstack.io/docs/player/components/buttons/play-button}
*/
export class PlayButton extends Component<PlayButtonProps> {
export class PlayButton extends Component<PlayButtonProps, {}, PlayButtonEvents> {
static props: PlayButtonProps = ToggleButtonController.props;

private _media!: MediaContext;
Expand Down
Loading

0 comments on commit b6d84af

Please sign in to comment.