Skip to content

Commit

Permalink
feat(player): more settings for default layout
Browse files Browse the repository at this point in the history
  • Loading branch information
bezumkin committed Jan 9, 2025
1 parent ac1fe3d commit eadd2dd
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 46 deletions.
40 changes: 40 additions & 0 deletions packages/vidstack/src/components/layouts/default/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,17 @@ export const defaultLayoutProps: DefaultLayoutProps = {
disableTimeSlider: false,
menuContainer: null,
menuGroup: 'bottom',
flatSettingsMenu: false,
noAudioGain: false,
noAudioTracks: false,
noMediaLoop: false,
noMediaSpeed: false,
noMediaQuality: false,
noGestures: false,
noAnnouncements: false,
noKeyboardAnimations: false,
noCaptionStyles: false,
noCaptions: false,
noModal: false,
noScrubGesture: false,
playbackRates: { min: 0, max: 2, step: 0.25 },
Expand Down Expand Up @@ -71,10 +79,30 @@ export interface DefaultLayoutProps {
* only applies to the large video layout.
*/
menuGroup: 'top' | 'bottom';
/**
* Do not split settings menu into submenus
*/
flatSettingsMenu: boolean;
/**
* Disable audio boost slider in the settings menu.
*/
noAudioGain: boolean;
/**
* Disable audio tracks in the settings menu.
*/
noAudioTracks: boolean;
/**
* Disable loop switch in the settings menu.
*/
noMediaLoop: boolean;
/**
* Disable media speed slider in the settings menu.
*/
noMediaSpeed: boolean;
/**
* Disable media quality slider in the settings menu.
*/
noMediaQuality: boolean;
/**
* Whether modal menus should be disabled when the small layout is active. A modal menu is
* a floating panel that floats up from the bottom of the screen (outside of the player). It's
Expand All @@ -97,10 +125,22 @@ export interface DefaultLayoutProps {
* Whether all gestures such as press to play or seek should not be active.
*/
noGestures: boolean;
/**
* Whether announcements should not be displayed.
*/
noAnnouncements: boolean;
/**
* Whether keyboard actions should not be displayed.
*/
noKeyboardAnimations: boolean;
/**
* Whether caption styles should not be displayed.
*/
noCaptionStyles: boolean;
/**
* Whether captions should not be displayed.
*/
noCaptions: boolean;
/**
* Whether the bitrate should be hidden in the settings quality hint.
*
Expand Down
2 changes: 2 additions & 0 deletions packages/vidstack/src/components/ui/menu/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,8 @@ export class Menu extends Component<MenuProps, {}, MenuEvents> {
#onResize = animationFrameThrottle(() => {
const content = peek(this.#content);
if (!content || __SERVER__) return;
// Disable resize for flatSettingsMenu because it works wrong with DefaultFontMenu()
if (content.getAttribute('flat') == 'true') return;

let height = 0,
styles = getComputedStyle(content),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,72 @@ import { DefaultMenuButton, DefaultMenuItem, DefaultMenuSection } from './items/

export function DefaultAccessibilityMenu() {
return $signal(() => {
const { translations } = useDefaultLayoutContext();
const {
flatSettingsMenu,
noAnnouncements,
noKeyboardAnimations,
noCaptionStyles,
translations,
} = useDefaultLayoutContext();

if (flatSettingsMenu()) {
const items: any[] = [];
if (!noAnnouncements()) {
items.push(DefaultAnnouncementsMenuCheckbox());
}
if (!noKeyboardAnimations()) {
items.push(DefaultKeyboardAnimationsMenuCheckbox());
}
if (!noCaptionStyles()) {
items.push(DefaultFontMenu());
}

return items.length
? DefaultMenuSection({
label: i18n(translations, 'Accessibility'),
children: items,
})
: null;
}

const items: any[] = [];
const topItems: any[] = [];
const bottomItems: any[] = [];

if (!noAnnouncements()) {
topItems.push(DefaultAnnouncementsMenuCheckbox());
}
if (!noKeyboardAnimations()) {
topItems.push(DefaultKeyboardAnimationsMenuCheckbox());
}
if (!noCaptionStyles()) {
bottomItems.push(DefaultFontMenu());
}

if (topItems.length) {
items.push(
DefaultMenuSection({
children: topItems,
}),
);
}
if (bottomItems.length) {
items.push(
DefaultMenuSection({
children: bottomItems,
}),
);
}

if (!items.length) return null;

return html`
<media-menu class="vds-accessibility-menu vds-menu">
${DefaultMenuButton({
label: () => i18n(translations, 'Accessibility'),
icon: 'menu-accessibility',
})}
<media-menu-items class="vds-menu-items">
${[
DefaultMenuSection({
children: [
DefaultAnnouncementsMenuCheckbox(),
DefaultKeyboardAnimationsMenuCheckbox(),
],
}),
DefaultMenuSection({
children: [DefaultFontMenu()],
}),
]}
</media-menu-items>
<media-menu-items class="vds-menu-items"> ${items} </media-menu-items>
</media-menu>
`;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import { DefaultMenuSliderItem, DefaultSliderParts, DefaultSliderSteps } from '.

export function DefaultAudioMenu() {
return $signal(() => {
const { noAudioGain, translations } = useDefaultLayoutContext(),
const { flatSettingsMenu, noAudioGain, noAudioTracks, translations } =
useDefaultLayoutContext(),
{ audioTracks, canSetAudioGain } = useMediaState(),
$disabled = computed(() => {
const hasGainSlider = canSetAudioGain() && !noAudioGain();
Expand All @@ -21,15 +22,33 @@ export function DefaultAudioMenu() {

if ($disabled()) return null;

const items: any[] = [];
if (!noAudioGain()) {
items.push(DefaultAudioBoostSection());
}
if (!noAudioTracks()) {
items.push(DefaultAudioTracksMenu());
}

if (!items.length) {
return null;
}

if (flatSettingsMenu())
return [
DefaultMenuSection({
label: i18n(translations, 'Audio'),
children: items,
}),
];

return html`
<media-menu class="vds-audio-menu vds-menu">
${DefaultMenuButton({
label: () => i18n(translations, 'Audio'),
icon: 'menu-audio',
})}
<media-menu-items class="vds-menu-items">
${[DefaultAudioTracksMenu(), DefaultAudioBoostSection()]}
</media-menu-items>
<media-menu-items class="vds-menu-items"> ${items} </media-menu-items>
</media-menu>
`;
});
Expand Down Expand Up @@ -119,13 +138,13 @@ function DefaultAudioGainSlider() {
function getGainMin() {
const { audioGains } = useDefaultLayoutContext(),
gains = audioGains();
return isArray(gains) ? gains[0] ?? 0 : gains.min;
return isArray(gains) ? (gains[0] ?? 0) : gains.min;
}

function getGainMax() {
const { audioGains } = useDefaultLayoutContext(),
gains = audioGains();
return isArray(gains) ? gains[gains.length - 1] ?? 300 : gains.max;
return isArray(gains) ? (gains[gains.length - 1] ?? 300) : gains.max;
}

function getGainStep() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,50 @@ import { i18n } from '../../../../../../components/layouts/default/translations'
import { useMediaState } from '../../../../../../core/api/media-context';
import { $signal } from '../../../../../lit/directives/signal';
import { $i18n } from '../utils';
import { DefaultMenuButton } from './items/menu-items';
import { DefaultMenuButton, DefaultMenuSection } from './items/menu-items';

export function DefaultCaptionsMenu() {
return $signal(() => {
const { translations } = useDefaultLayoutContext(),
{ hasCaptions } = useMediaState(),
$offText = $i18n(translations, 'Off');
const { flatSettingsMenu, noCaptions, translations } = useDefaultLayoutContext(),
{ hasCaptions } = useMediaState();

if (!hasCaptions()) return null;
if (!hasCaptions() || noCaptions()) return null;

if (flatSettingsMenu())
return [
DefaultMenuSection({
label: i18n(translations, 'Captions'),
children: [DefaultCaptionsMenuItems()],
}),
];

return html`
<media-menu class="vds-captions-menu vds-menu">
${DefaultMenuButton({
label: () => i18n(translations, 'Captions'),
icon: 'menu-captions',
})}
<media-menu-items class="vds-menu-items">
<media-captions-radio-group
class="vds-captions-radio-group vds-radio-group"
off-label=${$offText}
>
<template>
<media-radio class="vds-caption-radio vds-radio">
<slot name="menu-radio-check-icon" data-class="vds-icon"></slot>
<span class="vds-radio-label" data-part="label"></span>
</media-radio>
</template>
</media-captions-radio-group>
</media-menu-items>
<media-menu-items class="vds-menu-items"> ${DefaultCaptionsMenuItems()} </media-menu-items>
</media-menu>
`;
});
}

function DefaultCaptionsMenuItems() {
const { translations } = useDefaultLayoutContext(),
$offText = $i18n(translations, 'Off');

return html`
<media-captions-radio-group
class="vds-captions-radio-group vds-radio-group"
off-label=${$offText}
>
<template>
<media-radio class="vds-caption-radio vds-radio">
<slot name="menu-radio-check-icon" data-class="vds-icon"></slot>
<span class="vds-radio-label" data-part="label"></span>
</media-radio>
</template>
</media-captions-radio-group>
`;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,37 @@ import { DefaultMenuSliderItem, DefaultSliderParts, DefaultSliderSteps } from '.

export function DefaultPlaybackMenu() {
return $signal(() => {
const { translations } = useDefaultLayoutContext();
const { flatSettingsMenu, noMediaLoop, noMediaSpeed, noMediaQuality, translations } =
useDefaultLayoutContext();

const items: any[] = [];

if (!noMediaLoop()) {
items.push(
DefaultMenuSection({
children: DefaultLoopCheckbox(),
}),
);
}
if (!noMediaSpeed()) {
items.push(DefaultSpeedMenuSection());
}
if (!noMediaQuality()) {
items.push(DefaultQualityMenuSection());
}

if (!items.length) return null;

if (flatSettingsMenu()) return items;

return html`
<media-menu class="vds-playback-menu vds-menu">
${DefaultMenuButton({
label: () => i18n(translations, 'Playback'),
icon: 'menu-playback',
})}
<media-menu-items class="vds-menu-items">
${[
DefaultMenuSection({
children: DefaultLoopCheckbox(),
}),
DefaultSpeedMenuSection(),
DefaultQualityMenuSection(),
]}
${items}
</media-menu-items>
</media-menu>
`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export function DefaultSettingsMenu({
menuPortal,
noModal,
menuGroup,
flatSettingsMenu,
smallWhen: smWhen,
} = useDefaultLayoutContext(),
$placement = computed(() =>
Expand All @@ -57,6 +58,7 @@ export function DefaultSettingsMenu({
class="vds-settings-menu-items vds-menu-items"
placement=${$signal($placement)}
offset=${$signal($offset)}
flat="${flatSettingsMenu()}"
>
${$signal(() => {
if (!$isOpen()) {
Expand Down

0 comments on commit eadd2dd

Please sign in to comment.