UNPKG

bitmovin-player-ui

Version:
122 lines (105 loc) 3.61 kB
import { Container, ContainerConfig } from './Container'; import { UIInstanceManager } from '../UIManager'; import { MetadataLabel, MetadataLabelContent } from './labels/MetadataLabel'; import { PlayerAPI } from 'bitmovin-player'; import { Label } from './labels/Label'; import { Component, ComponentConfig } from './Component'; /** * Configuration interface for a {@link TitleBar}. * * @category Configs */ export interface TitleBarConfig extends ContainerConfig { /** * Specifies if the title bar should stay hidden when no label contains any text. * Applies to any label component with an isEmpty() method, not just MetadataLabels. * Default: false */ keepHiddenWithoutMetadata?: boolean; } /** * Displays a title bar containing a label with the title of the video or other contextual messages. * * @category Components */ export class TitleBar extends Container<TitleBarConfig> { constructor(config: TitleBarConfig = {}) { super(config); this.config = this.mergeConfig( config, { cssClass: 'ui-titlebar', hidden: true, keepHiddenWithoutMetadata: false, components: [ new Container({ components: [new MetadataLabel({ content: MetadataLabelContent.Title })], cssClasses: ['titlebar-row'], }), new Container({ components: [new MetadataLabel({ content: MetadataLabelContent.Description })], cssClasses: ['titlebar-row'], }), ], }, <TitleBarConfig>this.config, ); } configure(player: PlayerAPI, uimanager: UIInstanceManager): void { super.configure(player, uimanager); const config = this.getConfig(); let shouldBeShown = !this.isHidden(); let hasVisibleText = true; const checkTextAndUpdateVisibility = () => { hasVisibleText = this.hasNonEmptyComponents(this.getComponents()); if (this.isShown()) { if (config.keepHiddenWithoutMetadata && !hasVisibleText) { this.hide(); } } else if (shouldBeShown) { if (!config.keepHiddenWithoutMetadata || hasVisibleText) { this.show(); } } }; // Subscribe to any label-like component's text changes this.subscribeToTextChanges(this.getComponents(), checkTextAndUpdateVisibility); uimanager.onControlsShow.subscribe(() => { shouldBeShown = true; if (!config.keepHiddenWithoutMetadata || hasVisibleText) { this.show(); } }); uimanager.onControlsHide.subscribe(() => { shouldBeShown = false; this.hide(); }); checkTextAndUpdateVisibility(); } private hasNonEmptyComponents(components: Component<ComponentConfig>[]): boolean { for (const component of components) { if (hasIsEmpty(component) && !component.isEmpty()) { return true; } if (component instanceof Container) { if (this.hasNonEmptyComponents(component.getComponents())) { return true; } } } return false; } private subscribeToTextChanges(components: Component<ComponentConfig>[], onChange: () => void): void { for (const component of components) { if (component instanceof Label) { component.onTextChanged.subscribe(onChange); } if (component instanceof Container) { this.subscribeToTextChanges(component.getComponents(), onChange); } } } } function hasIsEmpty(obj: unknown): obj is { isEmpty: () => boolean } { return typeof obj === 'object' && obj !== null && typeof (obj as any).isEmpty === 'function'; }