diff --git a/assets/skin-super-modern/images/fullscreen.svg b/assets/skin-super-modern/images/fullscreen.svg index 11b92c81b..b1c38d50b 100644 --- a/assets/skin-super-modern/images/fullscreen.svg +++ b/assets/skin-super-modern/images/fullscreen.svg @@ -1,3 +1,6 @@ - - + + + + + diff --git a/assets/skin-super-modern/images/fullscreenX.svg b/assets/skin-super-modern/images/fullscreenX.svg index e129938f6..409a18c08 100644 --- a/assets/skin-super-modern/images/fullscreenX.svg +++ b/assets/skin-super-modern/images/fullscreenX.svg @@ -1,3 +1,6 @@ - - + + + + + diff --git a/assets/skin-super-modern/images/fullscreenXsmall.svg b/assets/skin-super-modern/images/fullscreenXsmall.svg deleted file mode 100644 index 409a18c08..000000000 --- a/assets/skin-super-modern/images/fullscreenXsmall.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/assets/skin-super-modern/images/fullscreensmall.svg b/assets/skin-super-modern/images/fullscreensmall.svg deleted file mode 100644 index b1c38d50b..000000000 --- a/assets/skin-super-modern/images/fullscreensmall.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/assets/skin-super-modern/images/loader.svg b/assets/skin-super-modern/images/loader.svg index 697a3b5cb..0c60ca01e 100644 --- a/assets/skin-super-modern/images/loader.svg +++ b/assets/skin-super-modern/images/loader.svg @@ -1,3 +1,18 @@ - - + + + + + + + + + + + + + + diff --git a/src/html/index.html b/src/html/index.html index 0e5c9334e..d92da4033 100644 --- a/src/html/index.html +++ b/src/html/index.html @@ -6,7 +6,6 @@ Bitmovin Player UI Demo - diff --git a/src/scss/bitmovinplayer-modern-ui.scss b/src/scss/bitmovinplayer-modern-ui.scss deleted file mode 100644 index 3e45ffbae..000000000 --- a/src/scss/bitmovinplayer-modern-ui.scss +++ /dev/null @@ -1 +0,0 @@ -@import 'skin-super-modern/skin'; diff --git a/src/scss/bitmovinplayer-ui.scss b/src/scss/bitmovinplayer-ui.scss index eeefcc38d..264a8a3da 100644 --- a/src/scss/bitmovinplayer-ui.scss +++ b/src/scss/bitmovinplayer-ui.scss @@ -1 +1,2 @@ @import 'skin-modern/skin'; +@import 'skin-super-modern/skin'; diff --git a/src/scss/skin-super-modern/_skin-modern-smallscreen.scss b/src/scss/skin-super-modern/_skin-modern-smallscreen.scss index 173e56069..f8f9d6d6a 100644 --- a/src/scss/skin-super-modern/_skin-modern-smallscreen.scss +++ b/src/scss/skin-super-modern/_skin-modern-smallscreen.scss @@ -3,14 +3,6 @@ &.#{$prefix}-ui-skin-modern-smallscreen { - .#{$prefix}-ui-fullscreentogglebutton { - background-image: url('../../assets/skin-super-modern/images/fullscreensmall.svg'); - - &.#{$prefix}-on { - background-image: url('../../assets/skin-super-modern/images/fullscreenXsmall.svg'); - } - } - // Do not display watermark in mobile view .#{$prefix}-ui-watermark { display: none; diff --git a/src/scss/skin-super-modern/_skin.scss b/src/scss/skin-super-modern/_skin.scss index 84320f233..f422101fe 100644 --- a/src/scss/skin-super-modern/_skin.scss +++ b/src/scss/skin-super-modern/_skin.scss @@ -49,7 +49,6 @@ @import 'components/subtitlesettingspaneltogglebutton'; @import 'components/touchcontroloverlay'; @import 'components/smallcenteredplaybacktogglebutton'; - @import 'components/loadingicon'; @import 'skin-ads'; @import 'skin-cast-receiver'; @import 'skin-modern-smallscreen'; diff --git a/src/scss/skin-super-modern/components/_bufferingoverlay.scss b/src/scss/skin-super-modern/components/_bufferingoverlay.scss index 9c54fa799..0b38e6749 100644 --- a/src/scss/skin-super-modern/components/_bufferingoverlay.scss +++ b/src/scss/skin-super-modern/components/_bufferingoverlay.scss @@ -64,7 +64,7 @@ } animation: #{$prefix}-fancy $buffering-animation-duration ease-in infinite; - background: url('../../assets/skin-modern/images/loader.svg') no-repeat center; + background: url('../../assets/skin-super-modern/images/loader.svg') no-repeat center; display: inline-block; height: 2em; margin: .2em; diff --git a/src/scss/skin-super-modern/components/_button.scss b/src/scss/skin-super-modern/components/_button.scss index 69aa6276f..d56865c8a 100644 --- a/src/scss/skin-super-modern/components/_button.scss +++ b/src/scss/skin-super-modern/components/_button.scss @@ -7,7 +7,7 @@ background-origin: content-box; background-position: center; background-repeat: no-repeat; - background-size: 1em; + background-size: 1.2em; border: 0; box-sizing: content-box; cursor: pointer; diff --git a/src/scss/skin-super-modern/components/_controlbar.scss b/src/scss/skin-super-modern/components/_controlbar.scss index 0002a1e0e..517d34da8 100644 --- a/src/scss/skin-super-modern/components/_controlbar.scss +++ b/src/scss/skin-super-modern/components/_controlbar.scss @@ -10,19 +10,23 @@ background: linear-gradient(to bottom, $color-transparent, $color-background-bars); box-sizing: border-box; line-height: 1em; - padding: 0 .75em; + padding: 1em 1em .5em; .#{$prefix}-controlbar-top, .#{$prefix}-controlbar-bottom { > .#{$prefix}-container-wrapper { display: flex; - margin: .25em 0; + margin: .5em 0; } } .#{$prefix}-controlbar-top { .#{$prefix}-ui-label { - font-size: .6em; + font-size: .9em; + } + + > .#{$prefix}-container-wrapper > * { + margin: 0 .5em; } } diff --git a/src/scss/skin-super-modern/components/_loadingicon.scss b/src/scss/skin-super-modern/components/_loadingicon.scss deleted file mode 100644 index 4e45b8f58..000000000 --- a/src/scss/skin-super-modern/components/_loadingicon.scss +++ /dev/null @@ -1,28 +0,0 @@ -@import '../variables'; -@import '../mixins'; - -@keyframes #{$prefix}-rotating { - from { - transform: rotate(0deg); - } - - to { - transform: rotate(360deg); - } -} - -.#{$prefix}-ui-loading-icon { - @extend %ui-container; - - background: url('../../assets/skin-super-modern/images/loader.svg') center no-repeat; - cursor: default; - display: none; - height: 2.5em; - outline: none; - width: 2.5em; - - &.#{$prefix}-loading { - animation: #{$prefix}-rotating 3s linear infinite; - display: block; - } -} diff --git a/src/scss/skin-super-modern/components/_playbacktimelabel.scss b/src/scss/skin-super-modern/components/_playbacktimelabel.scss index ee784c51d..d60c65776 100644 --- a/src/scss/skin-super-modern/components/_playbacktimelabel.scss +++ b/src/scss/skin-super-modern/components/_playbacktimelabel.scss @@ -3,9 +3,7 @@ .#{$prefix}-ui-playbacktimelabel { @extend %ui-label; - font-size: .8em; - font-weight: bold; - margin: 0 .5em; + font-weight: 500; text-transform: uppercase; &.#{$prefix}-ui-playbacktimelabel-live { diff --git a/src/scss/skin-super-modern/components/_seekbar.scss b/src/scss/skin-super-modern/components/_seekbar.scss index ca7f316c8..bfc749b52 100644 --- a/src/scss/skin-super-modern/components/_seekbar.scss +++ b/src/scss/skin-super-modern/components/_seekbar.scss @@ -1,7 +1,7 @@ @import '../variables'; @import '../mixins'; -$seekbar-height: .3em; +$seekbar-height: .3125em; // sass-lint:disable no-vendor-prefixes %bar { @@ -25,19 +25,16 @@ $seekbar-height: .3em; @include focusable; align-items: center; - display: flex; + font-size: 1em; height: 1em; - justify-content: center; - margin: 0 .5em; position: relative; width: 100%; $bar-inset: auto; - .#{$prefix}-seekbar-playbackposition-marker { @extend %bar; - @include seekbar-position-marker($seekbar-height * 2.2); + @include seekbar-position-marker($seekbar-height * 3); background-color: $color-highlight; border-radius: 50%; box-shadow: 0 0 3px 0 transparentize($color: #000, $amount: .75); @@ -49,15 +46,19 @@ $seekbar-height: .3em; @include hidden; @include focusable; - border-radius: 1em; cursor: pointer; font-size: 1em; height: $seekbar-height; margin: calc((1em - $seekbar-height) / 2) 0; - overflow: hidden; position: relative; width: 100%; + .#{$prefix}-seekbar-bars { + @extend %bar; + border-radius: 1em; + overflow: hidden; + } + .#{$prefix}-seekbar-backdrop { @extend %bar; background-color: transparentize($color-primary, .8); @@ -67,7 +68,7 @@ $seekbar-height: .3em; .#{$prefix}-seekbar-bufferlevel { @extend %bar; - background-color: transparentize($color-secondary, .3); + background-color: $color-primary; margin: $bar-inset 0; transition: .3s linear, .3s linear; transition-property: transform; diff --git a/src/scss/skin-super-modern/components/_seekbarlabel.scss b/src/scss/skin-super-modern/components/_seekbarlabel.scss index 8788c2068..cc021f31c 100644 --- a/src/scss/skin-super-modern/components/_seekbarlabel.scss +++ b/src/scss/skin-super-modern/components/_seekbarlabel.scss @@ -46,13 +46,13 @@ .#{$prefix}-seekbar-label-time { display: block; - font-weight: bold; + font-weight: 500; line-height: .8em; } .#{$prefix}-seekbar-label-title { display: block; - font-weight: bold; + font-weight: 500; margin-bottom: .3em; white-space: normal; } diff --git a/src/scss/skin-super-modern/components/_settingspanel.scss b/src/scss/skin-super-modern/components/_settingspanel.scss index 6a6a6a1c2..b59a2be1c 100644 --- a/src/scss/skin-super-modern/components/_settingspanel.scss +++ b/src/scss/skin-super-modern/components/_settingspanel.scss @@ -18,7 +18,6 @@ bottom: 3.5em; height: fit-content; max-height: 60%; - max-width: 140px; min-width: fit-content; overflow: hidden; overflow-y: auto; diff --git a/src/scss/skin-super-modern/components/_settingspanelpage.scss b/src/scss/skin-super-modern/components/_settingspanelpage.scss index 61ae0274d..bcb5e1e34 100644 --- a/src/scss/skin-super-modern/components/_settingspanelpage.scss +++ b/src/scss/skin-super-modern/components/_settingspanelpage.scss @@ -11,8 +11,8 @@ .#{$prefix}-container-wrapper > * { &.#{$prefix}-ui-label { display: inline-block; - font-size: .6em; - font-weight: 600; + font-size: .8em; + font-weight: 500; margin: 0; text-align: justify; width: 45%; @@ -74,8 +74,7 @@ } .#{$prefix}-ui-settings-panel-item { - height: 20px; - padding: 0 .4em; + padding: .5em .7em; white-space: nowrap; &:hover { diff --git a/src/scss/skin-super-modern/components/_titlebar.scss b/src/scss/skin-super-modern/components/_titlebar.scss index 4415be804..2aa77f2bb 100644 --- a/src/scss/skin-super-modern/components/_titlebar.scss +++ b/src/scss/skin-super-modern/components/_titlebar.scss @@ -9,11 +9,11 @@ background: linear-gradient(to top, $color-transparent, $color-background-bars); box-sizing: border-box; - padding: 0 .75em; + padding: .5em 1em 1em; pointer-events: none; > .#{$prefix}-container-wrapper { - padding: .75em 0; + padding: .5em; pointer-events: none; .#{$prefix}-label-metadata { @@ -24,7 +24,7 @@ cursor: default; display: block; font-size: 1.2em; - font-weight: bold; + font-weight: 500; text-shadow: 0 0 5px $color-black; white-space: normal; } diff --git a/src/scss/skin-super-modern/components/_volumeslider.scss b/src/scss/skin-super-modern/components/_volumeslider.scss index 877ed9db8..356b8f274 100644 --- a/src/scss/skin-super-modern/components/_volumeslider.scss +++ b/src/scss/skin-super-modern/components/_volumeslider.scss @@ -5,13 +5,13 @@ .#{$prefix}-ui-volumeslider { @extend %ui-seekbar; - .#{$prefix}-seekbar { - .#{$prefix}-seekbar-playbackposition-marker { - @include seekbar-position-marker($seekbar-height * 3 - .25em); - background-color: $color-highlight; - border: 0; - } + .#{$prefix}-seekbar-playbackposition-marker { + @include seekbar-position-marker($seekbar-height * 3 - .25em); + background-color: $color-highlight; + border: 0; + } + .#{$prefix}-seekbar { .#{$prefix}-seekbar-bufferlevel { display: none; } diff --git a/src/ts/components/loadingicon.ts b/src/ts/components/loadingicon.ts deleted file mode 100644 index 2e2cbcffa..000000000 --- a/src/ts/components/loadingicon.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { PlayerAPI } from 'bitmovin-player'; -import { UIInstanceManager } from '../uimanager'; -import { Container, ContainerConfig } from './container'; -import { Timeout } from '../timeout'; -import { EventDispatcher, NoArgs, Event } from '../eventdispatcher'; - -export interface LoadingIconConfig extends ContainerConfig { - /** - * Delay in milliseconds after which the buffering overlay will be displayed. Useful to bypass short stalls without - * displaying the overlay. Set to 0 to display the overlay instantly. - * Default: 1000ms (1 second) - */ - showDelayMs?: number; -} - -export class LoadingIcon extends Container { - private isLoading: boolean = false; - - private loadingEvents = { - loadingStartEvent: new EventDispatcher(), - loadingEndEvent: new EventDispatcher(), - }; - - constructor(config: LoadingIconConfig = {}) { - super(config); - - this.config = this.mergeConfig(config, { - cssClass: 'ui-loading-icon', - role: 'icon', - showDelayMs: 1000, - }, this.config); - } - - configure(player: PlayerAPI, uimanager: UIInstanceManager): void { - super.configure(player, uimanager); - - let config = this.getConfig(); - - let overlayShowTimeout = new Timeout(config.showDelayMs, () => { - this.startLoader(); - }); - - let showOverlay = () => { - overlayShowTimeout.start(); - }; - - let hideOverlay = () => { - overlayShowTimeout.clear(); - this.stopLoader(); - }; - - player.on(player.exports.PlayerEvent.StallStarted, showOverlay); - player.on(player.exports.PlayerEvent.StallEnded, hideOverlay); - player.on(player.exports.PlayerEvent.Play, showOverlay); - player.on(player.exports.PlayerEvent.Playing, hideOverlay); - player.on(player.exports.PlayerEvent.Paused, hideOverlay); - player.on(player.exports.PlayerEvent.Seek, showOverlay); - player.on(player.exports.PlayerEvent.Seeked, hideOverlay); - player.on(player.exports.PlayerEvent.TimeShift, showOverlay); - player.on(player.exports.PlayerEvent.TimeShifted, hideOverlay); - player.on(player.exports.PlayerEvent.SourceUnloaded, hideOverlay); - - // Show overlay if player is already stalled at init - if (player.isStalled()) { - this.startLoader(); - } - } - - private startLoader(): void { - if (!this.isLoading) { - this.isLoading = true; - this.onLoadingStartEvent(); - this.getDomElement().addClass(this.prefixCss('loading')); - } - } - - private stopLoader(): void { - if (this.isLoading) { - this.isLoading = false; - this.onLoadingEndEvent(); - this.getDomElement().removeClass(this.prefixCss('loading')); - } - } - - public onLoadingStartEvent(): void { - this.loadingEvents.loadingStartEvent.dispatch(this); - } - - public onLoadingEndEvent(): void { - this.loadingEvents.loadingEndEvent.dispatch(this); - } - - public isSpinning(): boolean { - return this.isLoading; - } - - get loadingStartEvent(): Event { - return this.loadingEvents.loadingStartEvent.getEvent(); - } - - get loadingEndEvent(): Event { - return this.loadingEvents.loadingEndEvent.getEvent(); - } -} \ No newline at end of file diff --git a/src/ts/components/seekbar.ts b/src/ts/components/seekbar.ts index e16e0d0a9..22e086ee2 100644 --- a/src/ts/components/seekbar.ts +++ b/src/ts/components/seekbar.ts @@ -31,12 +31,6 @@ export interface SeekBarConfig extends ComponentConfig { * Bar will be vertical instead of horizontal if set to true. */ vertical?: boolean; - /** - * If set to true the seekBarPlaybackPositionMarker will be rendered - * directly inside the seekbar container. Necessary when using the super-modern-ui skin - * Default: false - */ - renderSeekBarPlaybackPositionMarkerInOuterSeekBar?: boolean; /** * The interval in milliseconds in which the playback position on the seek bar will be updated. The shorter the * interval, the smoother it looks and the more resource intense it is. The update interval will be kept as steady @@ -171,7 +165,6 @@ export class SeekBar extends Component { snappingRange: 1, enableSeekPreview: true, snappingEnabled: true, - renderSeekBarPlaybackPositionMarkerInOuterSeekBar: false, }, this.config); this.label = this.config.label; @@ -249,10 +242,17 @@ export class SeekBar extends Component { uimanager.onControlsShow.subscribe(() => { this.isUiShown = true; + if (!player.isLive() && !this.smoothPlaybackPositionUpdater.isActive()) { + playbackPositionHandler(null, true); + this.smoothPlaybackPositionUpdater.start(); + } }); uimanager.onControlsHide.subscribe(() => { this.isUiShown = false; + if (this.smoothPlaybackPositionUpdater.isActive()) { + this.smoothPlaybackPositionUpdater.clear(); + } }); let isPlaying = false; @@ -294,7 +294,7 @@ export class SeekBar extends Component { // Update playback position only in paused state or in the initial startup state where player is neither // paused nor playing. Playback updates are handled in the Timeout below. const isInInitialStartupState = this.config.smoothPlaybackPositionUpdateIntervalMs === SeekBar.SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED - || forceUpdate || player.isPaused(); + || forceUpdate || player.isPaused(); const isNeitherPausedNorPlaying = player.isPaused() === player.isPlaying(); if ((isInInitialStartupState || isNeitherPausedNorPlaying) && !this.isSeeking()) { @@ -330,12 +330,12 @@ export class SeekBar extends Component { scrubbing = false; }; - let onPlayerSeeked = (event: PlayerEventBase = null, forceUpdate: boolean = false ) => { + let onPlayerSeeked = (event: PlayerEventBase = null) => { isPlayerSeeking = false; this.setSeeking(false); // update playback position when a seek has finished - playbackPositionHandler(event, forceUpdate); + playbackPositionHandler(event, true); }; let restorePlayingState = function () { @@ -668,6 +668,10 @@ export class SeekBar extends Component { }); this.seekBar = seekBar; + const seekBarBarsContainer = new DOM('div', { + 'class': this.prefixCss('seekbar-bars'), + }); + // Indicator that shows the buffer fill level let seekBarBufferLevel = new DOM('div', { 'class': this.prefixCss('seekbar-bufferlevel'), @@ -703,12 +707,10 @@ export class SeekBar extends Component { }); this.seekBarMarkersContainer = seekBarChapterMarkersContainer; - seekBar.append(this.seekBarBackdrop, this.seekBarBufferPosition, this.seekBarSeekPosition, + seekBarBarsContainer.append(this.seekBarBackdrop, this.seekBarBufferPosition, this.seekBarSeekPosition, this.seekBarPlaybackPosition, this.seekBarMarkersContainer); - if (!this.config.renderSeekBarPlaybackPositionMarkerInOuterSeekBar) { - seekBar.append(this.seekBarPlaybackPositionMarker); - } + seekBar.append(seekBarBarsContainer, this.seekBarPlaybackPositionMarker); let seeking = false; @@ -747,14 +749,12 @@ export class SeekBar extends Component { this.onSeekedEvent(targetPercentage); }; - let domElementToListen: DOM = this.config.renderSeekBarPlaybackPositionMarkerInOuterSeekBar ? seekBarContainer : seekBar; - // A seek always start with a touchstart or mousedown directly on the seekbar. // To track a mouse seek also outside the seekbar (for touch events this works automatically), // so the user does not need to take care that the mouse always stays on the seekbar, we attach the mousemove // and mouseup handlers to the whole document. A seek is triggered when the user lifts the mouse key. // A seek mouse gesture is thus basically a click with a long time frame between down and up events. - domElementToListen.on('touchstart mousedown', (e: MouseEvent | TouchEvent) => { + seekBar.on('touchstart mousedown', (e: MouseEvent | TouchEvent) => { let isTouchEvent = BrowserUtils.isTouchSupported && this.isTouchEvent(e); // Prevent selection of DOM elements (also prevents mousedown if current event is touchstart) @@ -776,7 +776,7 @@ export class SeekBar extends Component { }); // Display seek target indicator when mouse hovers or finger slides over seekbar - domElementToListen.on('touchmove mousemove', (e: MouseEvent | TouchEvent) => { + seekBar.on('touchmove mousemove', (e: MouseEvent | TouchEvent) => { e.preventDefault(); if (seeking) { @@ -794,7 +794,7 @@ export class SeekBar extends Component { }); // Hide seek target indicator when mouse or finger leaves seekbar - domElementToListen.on('touchend mouseleave', (e: MouseEvent | TouchEvent) => { + seekBar.on('touchend mouseleave', (e: MouseEvent | TouchEvent) => { e.preventDefault(); this.setSeekPosition(0); @@ -810,10 +810,6 @@ export class SeekBar extends Component { seekBarContainer.append(this.label.getDomElement()); } - if (this.config.renderSeekBarPlaybackPositionMarkerInOuterSeekBar) { - seekBarContainer.append(seekBarPlaybackPositionMarker); - } - return seekBarContainer; } @@ -1107,7 +1103,7 @@ export class SeekBar extends Component { this.refreshPlaybackPosition(); } - /** + /** * Checks if TouchEvent is supported. * @returns {boolean} true if TouchEvent not undefined, else false */ diff --git a/src/ts/components/touchcontroloverlay.ts b/src/ts/components/touchcontroloverlay.ts index 6e3c970fc..e9167716c 100644 --- a/src/ts/components/touchcontroloverlay.ts +++ b/src/ts/components/touchcontroloverlay.ts @@ -7,7 +7,6 @@ import { Timeout } from '../timeout'; import { HTMLElementWithComponent } from '../dom'; import { Label, LabelConfig } from './label'; import { i18n } from '../localization/i18n'; -import { LoadingIcon } from './loadingicon'; export interface TouchControlOverlayConfig extends ContainerConfig { /** @@ -60,7 +59,6 @@ export class TouchControlOverlay extends Container { }; private playbackToggleButton: SmallCenteredPlaybackToggleButton; - private loadingIcon: LoadingIcon; private seekForwardLabel: Label; private seekBackwardLabel: Label; @@ -77,8 +75,6 @@ export class TouchControlOverlay extends Container { enterFullscreenOnInitialPlayback: Boolean(config.enterFullscreenOnInitialPlayback), }); - this.loadingIcon = new LoadingIcon(); - this.seekForwardLabel = new Label({text: '', for: this.getConfig().id, cssClass: 'seek-forward-label', hidden: true}); this.seekBackwardLabel = new Label({text: '', for: this.getConfig().id, cssClass: 'seek-backward-label', hidden: true}); @@ -94,27 +90,6 @@ export class TouchControlOverlay extends Container { configure(player: PlayerAPI, uimanager: UIInstanceManager): void { super.configure(player, uimanager); - this.loadingIcon.configure(player, uimanager); - - let showLoadingIcon = () => { - this.removeComponent(this.playbackToggleButton); - this.addComponent(this.loadingIcon); - this.updateComponents(); - }; - - let hideLoadingIcon = () => { - this.removeComponent(this.loadingIcon); - this.addComponent(this.playbackToggleButton); - this.updateComponents(); - }; - - if (this.loadingIcon.isSpinning()) { - showLoadingIcon(); - } - - this.loadingIcon.loadingStartEvent.subscribe(showLoadingIcon); - this.loadingIcon.loadingEndEvent.subscribe(hideLoadingIcon); - let playerSeekTime = 0; let startSeekTime = 0; @@ -132,7 +107,6 @@ export class TouchControlOverlay extends Container { this.playbackToggleButton.show(); }); - this.touchControlEvents.onSeekBackward.subscribe(() => { playerSeekTime -= this.config.seekTime; player.seek(playerSeekTime); diff --git a/src/ts/uifactory.ts b/src/ts/uifactory.ts index 8f361b671..f2d3f638d 100644 --- a/src/ts/uifactory.ts +++ b/src/ts/uifactory.ts @@ -469,7 +469,7 @@ export namespace UIFactory { let settingsPanel = new ModernSettingsPanel({ components: [mainSettingsPanelPage], hidden: true, - pageTransitionAnimation: false, + pageTransitionAnimation: true, hideDelay: -1, }); @@ -492,7 +492,7 @@ export namespace UIFactory { timeLabelMode: PlaybackTimeLabelMode.CurrentTime, hideInLivePlayback: true, }), - new SeekBar({ label: new SeekBarLabel(), renderSeekBarPlaybackPositionMarkerInOuterSeekBar: true }), + new SeekBar({ label: new SeekBarLabel() }), new PlaybackTimeLabel({ timeLabelMode: PlaybackTimeLabelMode.TotalTime, cssClasses: ['text-right'], @@ -517,12 +517,9 @@ export namespace UIFactory { return new UIContainer({ components: [ subtitleOverlay, - + new BufferingOverlay(), new CastStatusOverlay(), - // TODO: make an overlay for the quickseek buttons/double tab new TouchControlOverlay(), - // TODO: make a new buffer overlay - // new BufferingOverlay(), new RecommendationOverlay(), controlBar, new TitleBar({ @@ -531,7 +528,6 @@ export namespace UIFactory { new CastToggleButton(), new AirPlayToggleButton(), new VRToggleButton(), - // TODO: make a Share button ], }), settingsPanel, @@ -547,8 +543,108 @@ export namespace UIFactory { }); } - export function superModerUI() { - return new UIContainer({}); + export function superModernUI() { + let subtitleOverlay = new SubtitleOverlay(); + + let mainSettingsPanelPage: SettingsPanelPage; + + const components: Container[] = [ + new ModernSettingsPanelItem(i18n.getLocalizer('settings.video.quality'), new VideoQualitySelectBox()), + new ModernSettingsPanelItem(i18n.getLocalizer('speed'), new PlaybackSpeedSelectBox()), + new ModernSettingsPanelItem(i18n.getLocalizer('settings.audio.track'), new AudioTrackSelectBox()), + new ModernSettingsPanelItem(i18n.getLocalizer('settings.audio.quality'), new AudioQualitySelectBox()), + ]; + + mainSettingsPanelPage = new ModernSettingsPanelPage({ + components, + }); + + let settingsPanel = new ModernSettingsPanel({ + components: [mainSettingsPanelPage], + hidden: true, + pageTransitionAnimation: true, + }); + + // let subtitleSettingsPanelPage = new SubtitleSettingsPanelPage({ + // settingsPanel: settingsPanel, + // overlay: subtitleOverlay, + // }); + // + // let subtitleSettingsOpenButton = new SettingsPanelPageOpenButton({ + // targetPage: subtitleSettingsPanelPage, + // container: settingsPanel, + // ariaLabel: i18n.getLocalizer('settings.subtitles'), + // text: i18n.getLocalizer('open'), + // }); + + const subtitleSelectBox = new SubtitleSelectBox(); + let subtitleSelectItem = new ModernSettingsPanelItem( + new Label({ text: i18n.getLocalizer('settings.subtitles') } as LabelConfig), + subtitleSelectBox, + null, + { + role: 'menubar', + }, + ); + mainSettingsPanelPage.addComponent(subtitleSelectItem); + + // settingsPanel.addComponent(subtitleSettingsPanelPage); + + let controlBar = new ControlBar({ + components: [ + new Container({ + components: [ + new PlaybackTimeLabel({ + timeLabelMode: PlaybackTimeLabelMode.CurrentTime, + hideInLivePlayback: true, + }), + new SeekBar({ label: new SeekBarLabel() }), + new PlaybackTimeLabel({ + timeLabelMode: PlaybackTimeLabelMode.TotalTime, + cssClasses: ['text-right'], + }), + ], + cssClasses: ['controlbar-top'], + }), + new Container({ + components: [ + new PlaybackToggleButton(), + new VolumeToggleButton(), + new VolumeSlider(), + new Spacer(), + new PictureInPictureToggleButton(), + new AirPlayToggleButton(), + new CastToggleButton(), + new VRToggleButton(), + new SettingsToggleButton({ settingsPanel: settingsPanel }), + new FullscreenToggleButton(), + ], + cssClasses: ['controlbar-bottom'], + }), + ], + }); + + return new UIContainer({ + components: [ + subtitleOverlay, + new BufferingOverlay(), + new PlaybackToggleOverlay(), + new CastStatusOverlay(), + controlBar, + new TitleBar(), + new RecommendationOverlay(), + new Watermark(), + settingsPanel, + new ErrorMessageOverlay(), + ], + hideDelay: 2000, + hidePlayerStateExceptions: [ + PlayerUtils.PlayerState.Prepared, + PlayerUtils.PlayerState.Paused, + PlayerUtils.PlayerState.Finished, + ], + cssClasses: ['ui-skin-super-modern'], + }); } export function buildSuperModernUI(player: PlayerAPI, config: UIConfig = {}): UIManager { @@ -584,7 +680,7 @@ export namespace UIFactory { }, }, { - ui: modernUI(config), + ui: superModernUI(), condition: (context: UIConditionContext) => { return !context.isAd && !context.adRequiresUi; },