Skip to content

Commit

Permalink
Merge pull request #20 from THEOplayer/rework-settings-menu
Browse files Browse the repository at this point in the history
Rework settings menu
  • Loading branch information
MattiasBuelens authored Apr 4, 2023
2 parents 6cbcbc6 + c315a7d commit 5473edb
Show file tree
Hide file tree
Showing 17 changed files with 145 additions and 73 deletions.
4 changes: 4 additions & 0 deletions .idea/web-ui.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 2 additions & 9 deletions docs/examples/nitflex.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,9 @@
</theoplayer-menu-button>
<theoplayer-button><span class="material-symbols-sharp material-symbols-sharp-fill">skip_next</span> Next episode</theoplayer-button>
</theoplayer-control-bar>
<theoplayer-menu id="playback-speed-menu" slot="menu" menu-close-on-input hidden>
<theoplayer-playback-rate-menu id="playback-speed-menu" slot="menu" menu-close-on-input hidden>
<span slot="heading">Playback speed</span>
<theoplayer-playback-rate-radio-group>
<theoplayer-radio-button value="0.5">0.5x</theoplayer-radio-button>
<theoplayer-radio-button value="0.75">0.75x</theoplayer-radio-button>
<theoplayer-radio-button value="1">1x (normal)</theoplayer-radio-button>
<theoplayer-radio-button value="1.25">1.25x</theoplayer-radio-button>
<theoplayer-radio-button value="1.5">1.5x</theoplayer-radio-button>
</theoplayer-playback-rate-radio-group>
</theoplayer-menu>
</theoplayer-playback-rate-menu>
<theoplayer-language-menu id="language-menu" slot="menu" hidden>
<span slot="heading">Audio and subtitles</span>
</theoplayer-language-menu>
Expand Down
3 changes: 0 additions & 3 deletions src/DefaultUI.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
</div>
<span class="theoplayer-spacer"></span>
<theoplayer-language-menu-button menu="language-menu" mobile-only ad-hidden></theoplayer-language-menu-button>
<theoplayer-settings-menu-button menu="settings-menu" mobile-only ad-hidden></theoplayer-settings-menu-button>
<theoplayer-airplay-button mobile-only ad-hidden></theoplayer-airplay-button>
<theoplayer-chromecast-button mobile-only ad-hidden></theoplayer-chromecast-button>
<slot name="top-control-bar"></slot>
Expand Down Expand Up @@ -38,15 +37,13 @@
<theoplayer-time-display show-duration remaining-when-live></theoplayer-time-display>
<span class="theoplayer-spacer"></span>
<theoplayer-language-menu-button menu="language-menu" mobile-hidden ad-hidden></theoplayer-language-menu-button>
<theoplayer-settings-menu-button menu="settings-menu" mobile-hidden ad-hidden></theoplayer-settings-menu-button>
<theoplayer-airplay-button mobile-hidden ad-hidden></theoplayer-airplay-button>
<theoplayer-chromecast-button mobile-hidden ad-hidden></theoplayer-chromecast-button>
<slot name="bottom-control-bar"></slot>
<theoplayer-fullscreen-button></theoplayer-fullscreen-button>
</theoplayer-control-bar>
</div>
<theoplayer-language-menu id="language-menu" slot="menu" hidden></theoplayer-language-menu>
<theoplayer-settings-menu id="settings-menu" slot="menu" hidden></theoplayer-settings-menu>
<theoplayer-error-display slot="error"></theoplayer-error-display>
<slot name="menu" slot="menu"></slot>
</theoplayer-ui>
Original file line number Diff line number Diff line change
@@ -1,26 +1,37 @@
import * as shadyCss from '@webcomponents/shadycss';
import { buttonTemplate } from './Button';
import { MenuButton } from './MenuButton';
import { StateReceiverMixin } from './StateReceiverMixin';
import { setTextContent } from '../util/CommonUtils';
import type { VideoQuality } from 'theoplayer';
import { formatQualityLabel } from '../util/TrackUtils';

const template = document.createElement('template');
template.innerHTML = buttonTemplate(`<slot>Automatic</slot>`);
shadyCss.prepareTemplate(template, 'theoplayer-active-quality-menu-button');
import * as shadyCss from '@webcomponents/shadycss';

/**
* @group Components
*/
export class ActiveQualityMenuButton extends StateReceiverMixin(MenuButton, ['activeVideoQuality', 'targetVideoQualities']) {
private readonly _slotEl: HTMLSlotElement;
export class ActiveQualityDisplay extends StateReceiverMixin(HTMLElement, ['activeVideoQuality', 'targetVideoQualities']) {
private readonly _spanEl: HTMLSpanElement;
private _activeVideoQuality: VideoQuality | undefined = undefined;
private _targetVideoQualities: VideoQuality[] | undefined = undefined;

constructor() {
super({ template });
this._slotEl = this.shadowRoot!.querySelector('slot')!;
super();
const shadowRoot = this.attachShadow({ mode: 'open' });
this._spanEl = document.createElement('span');
shadowRoot.appendChild(this._spanEl);

this._upgradeProperty('activeVideoQuality');
this._upgradeProperty('targetVideoQualities');
}

connectedCallback(): void {
shadyCss.styleElement(this);
}

protected _upgradeProperty(prop: keyof this) {
if (this.hasOwnProperty(prop)) {
let value = this[prop];
delete this[prop];
this[prop] = value;
}
}

get activeVideoQuality(): VideoQuality | undefined {
Expand Down Expand Up @@ -57,8 +68,8 @@ export class ActiveQualityMenuButton extends StateReceiverMixin(MenuButton, ['ac
// Automatic quality selection: "Automatic" or "Automatic (720p)"
label = `Automatic${qualityLabel ? ` (${qualityLabel})` : ''}`;
}
setTextContent(this._slotEl, label);
setTextContent(this._spanEl, label);
}
}

customElements.define('theoplayer-active-quality-menu-button', ActiveQualityMenuButton);
customElements.define('theoplayer-active-quality-display', ActiveQualityDisplay);
8 changes: 8 additions & 0 deletions src/components/LanguageMenu.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
.theoplayer-menu-heading {
flex-grow: 1;
}

.theoplayer-menu-heading-button {
align-self: flex-end;
}

[part='audio'],
[part='subtitles'],
theoplayer-track-radio-group {
Expand Down
8 changes: 7 additions & 1 deletion src/components/LanguageMenu.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<theoplayer-menu>
<span slot="heading"><slot name="heading">Language</slot></span>
<span class="theoplayer-menu-heading" slot="heading"><slot name="heading">Language</slot></span>
<theoplayer-settings-menu-button
class="theoplayer-menu-heading-button"
menu="subtitle-options-menu"
slot="heading"
></theoplayer-settings-menu-button>
<div part="content">
<div part="audio">
<h2>Audio</h2>
Expand All @@ -11,3 +16,4 @@ <h2>Subtitles</h2>
</div>
</div>
</theoplayer-menu>
<theoplayer-text-track-style-menu id="subtitle-options-menu"></theoplayer-text-track-style-menu>
43 changes: 43 additions & 0 deletions src/components/PlaybackRateDisplay.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { StateReceiverMixin } from './StateReceiverMixin';
import { setTextContent } from '../util/CommonUtils';
import * as shadyCss from '@webcomponents/shadycss';

/**
* @group Components
*/
export class PlaybackRateDisplay extends StateReceiverMixin(HTMLElement, ['playbackRate']) {
private readonly _spanEl: HTMLSpanElement;
private _playbackRate: number = 1;

constructor() {
super();
const shadowRoot = this.attachShadow({ mode: 'open' });
this._spanEl = document.createElement('span');
shadowRoot.appendChild(this._spanEl);

this._upgradeProperty('playbackRate');
}

connectedCallback(): void {
shadyCss.styleElement(this);
}

protected _upgradeProperty(prop: keyof this) {
if (this.hasOwnProperty(prop)) {
let value = this[prop];
delete this[prop];
this[prop] = value;
}
}

get playbackRate(): number {
return this._playbackRate;
}

set playbackRate(value: number) {
this._playbackRate = value;
setTextContent(this._spanEl, value === 1 ? 'Normal' : `${value}x`);
}
}

customElements.define('theoplayer-playback-rate-display', PlaybackRateDisplay);
8 changes: 8 additions & 0 deletions src/components/PlaybackRateMenu.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<theoplayer-playback-rate-radio-group>
<theoplayer-radio-button value="0.25">0.25x</theoplayer-radio-button>
<theoplayer-radio-button value="0.5">0.5x</theoplayer-radio-button>
<theoplayer-radio-button value="1">Normal</theoplayer-radio-button>
<theoplayer-radio-button value="1.25">1.25x</theoplayer-radio-button>
<theoplayer-radio-button value="1.5">1.5x</theoplayer-radio-button>
<theoplayer-radio-button value="2">2x</theoplayer-radio-button>
</theoplayer-playback-rate-radio-group>
21 changes: 21 additions & 0 deletions src/components/PlaybackRateMenu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import * as shadyCss from '@webcomponents/shadycss';
import { Menu, menuTemplate } from './Menu';
import playbackRateMenuHtml from './PlaybackRateMenu.html';
import './PlaybackRateRadioGroup';

const template = document.createElement('template');
template.innerHTML = menuTemplate(`<span slot="heading"><slot name="heading">Playback speed</slot></span>`, playbackRateMenuHtml);
shadyCss.prepareTemplate(template, 'theoplayer-playback-rate-menu');

/**
* A menu to change the playback rate of the player.
*
* @group Components
*/
export class PlaybackRateMenu extends Menu {
constructor() {
super({ template });
}
}

customElements.define('theoplayer-playback-rate-menu', PlaybackRateMenu);
28 changes: 6 additions & 22 deletions src/components/PlaybackRateMenuButton.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,21 @@
import * as shadyCss from '@webcomponents/shadycss';
import { buttonTemplate } from './Button';
import { MenuButton } from './MenuButton';
import { StateReceiverMixin } from './StateReceiverMixin';
import { setTextContent } from '../util/CommonUtils';
import speedIcon from '../icons/speed.svg';

const template = document.createElement('template');
template.innerHTML = buttonTemplate(`<slot>1x</slot>`);
shadyCss.prepareTemplate(template, 'theoplayer-playback-rate-menu-button');
template.innerHTML = buttonTemplate(`<span part="icon"><slot>${speedIcon}</slot></span>`);
shadyCss.prepareTemplate(template, 'theoplayer-playback-rate-button');

/**
* A menu button that shows the current playback rate, and is intended to open a playback rate menu.
* A menu button that opens a [playback rate menu]{@link PlaybackRateMenu}.
*
* @attribute menu - The ID of the playback rate menu.
* @group Components
*/
export class PlaybackRateMenuButton extends StateReceiverMixin(MenuButton, ['playbackRate']) {
private readonly _slotEl: HTMLSlotElement;
private _playbackRate: number = 1;

export class PlaybackRateMenuButton extends MenuButton {
constructor() {
super({ template });
this._slotEl = this.shadowRoot!.querySelector('slot')!;
}

/**
* The current playback rate.
*/
get playbackRate(): number {
return this._playbackRate;
}

set playbackRate(value: number) {
this._playbackRate = value;
setTextContent(this._slotEl, value === 1 ? 'Normal' : `${value}x`);
}
}

Expand Down
23 changes: 8 additions & 15 deletions src/components/SettingsMenu.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,19 @@
<span slot="heading"><slot name="heading">Settings</slot></span>
<div class="theoplayer-menu-table">
<span>Quality</span>
<theoplayer-active-quality-menu-button menu="quality-menu"></theoplayer-active-quality-menu-button>
<theoplayer-menu-button menu="quality-menu">
<theoplayer-active-quality-display></theoplayer-active-quality-display>
</theoplayer-menu-button>
<span>Playback speed</span>
<theoplayer-playback-rate-menu-button menu="playback-rate-menu"></theoplayer-playback-rate-menu-button>
<span>Subtitles</span>
<theoplayer-menu-button menu="subtitle-options-menu">Options</theoplayer-menu-button>
<theoplayer-menu-button menu="playback-rate-menu">
<theoplayer-playback-rate-display></theoplayer-playback-rate-display>
</theoplayer-menu-button>
</div>
</theoplayer-menu>
<theoplayer-menu id="quality-menu" menu-close-on-input hidden>
<span slot="heading">Quality</span>
<theoplayer-quality-radio-group></theoplayer-quality-radio-group>
</theoplayer-menu>
<theoplayer-menu id="playback-rate-menu" menu-close-on-input hidden>
<theoplayer-playback-rate-menu id="playback-rate-menu" menu-close-on-input hidden>
<span slot="heading">Playback speed</span>
<theoplayer-playback-rate-radio-group>
<theoplayer-radio-button value="0.25">0.25x</theoplayer-radio-button>
<theoplayer-radio-button value="0.5">0.5x</theoplayer-radio-button>
<theoplayer-radio-button value="1">Normal</theoplayer-radio-button>
<theoplayer-radio-button value="1.25">1.25x</theoplayer-radio-button>
<theoplayer-radio-button value="1.5">1.5x</theoplayer-radio-button>
<theoplayer-radio-button value="2">2x</theoplayer-radio-button>
</theoplayer-playback-rate-radio-group>
</theoplayer-menu>
<theoplayer-text-track-style-menu id="subtitle-options-menu"></theoplayer-text-track-style-menu>
</theoplayer-playback-rate-menu>
5 changes: 3 additions & 2 deletions src/components/SettingsMenu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import * as shadyCss from '@webcomponents/shadycss';
import { MenuGroup, menuGroupTemplate } from './MenuGroup';
import settingsMenuHtml from './SettingsMenu.html';
import menuTableCss from './MenuTable.css';
import './ActiveQualityMenuButton';
import './PlaybackRateMenuButton';
import './ActiveQualityDisplay';
import './PlaybackRateDisplay';
import './PlaybackRateMenu';

const template = document.createElement('template');
template.innerHTML = menuGroupTemplate(settingsMenuHtml, menuTableCss);
Expand Down
6 changes: 3 additions & 3 deletions src/components/TextTrackStyleDisplay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ export class TextTrackStyleDisplay extends StateReceiverMixin(HTMLElement, ['pla
const shadowRoot = this.attachShadow({ mode: 'open' });
this._spanEl = document.createElement('span');
shadowRoot.appendChild(this._spanEl);

this._upgradeProperty('property');
this._upgradeProperty('player');
}

connectedCallback(): void {
shadyCss.styleElement(this);

this._upgradeProperty('property');
this._upgradeProperty('player');

if (!this.hasAttribute(Attribute.PROPERTY)) {
this.property = 'fontColor';
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/TextTrackStyleMenu.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.theoplayer-text-track-style-menu span {
.theoplayer-menu-heading {
flex-grow: 1;
}

.theoplayer-text-track-style-menu theoplayer-text-track-style-reset-button {
.theoplayer-menu-heading-button {
align-self: flex-end;
}
4 changes: 2 additions & 2 deletions src/components/TextTrackStyleMenu.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<theoplayer-menu class="theoplayer-text-track-style-menu">
<span slot="heading"><slot name="heading">Subtitle options</slot></span>
<theoplayer-text-track-style-reset-button slot="heading"></theoplayer-text-track-style-reset-button>
<span class="theoplayer-menu-heading" slot="heading"><slot name="heading">Subtitle options</slot></span>
<theoplayer-text-track-style-reset-button class="theoplayer-menu-heading-button" slot="heading"></theoplayer-text-track-style-reset-button>
<div class="theoplayer-menu-table">
<span>Font family</span>
<theoplayer-menu-button menu="font-family-menu">
Expand Down
4 changes: 3 additions & 1 deletion src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ export * from './LanguageMenu';
export * from './LanguageMenuButton';
export * from './PlaybackRateRadioGroup';
export * from './PlaybackRateMenuButton';
export * from './ActiveQualityMenuButton';
export * from './PlaybackRateMenu';
export * from './PlaybackRateDisplay';
export * from './ActiveQualityDisplay';
export * from './QualityRadioButton';
export * from './QualityRadioGroup';
export * from './TextTrackStyleRadioGroup';
Expand Down
1 change: 1 addition & 0 deletions src/icons/speed.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 5473edb

Please sign in to comment.