UNPKG

bitmovin-player-ui

Version:
120 lines (106 loc) 4.09 kB
import { ToggleButton, ToggleButtonConfig } from '../buttons/ToggleButton'; import { SettingsPanel, SettingsPanelConfig } from './SettingsPanel'; import { UIInstanceManager } from '../../UIManager'; import { Component, ComponentConfig } from '../Component'; import { ArrayUtils } from '../../utils/ArrayUtils'; import { PlayerAPI } from 'bitmovin-player'; import { i18n } from '../../localization/i18n'; /** * Configuration interface for the {@link SettingsToggleButton}. * * @category Configs */ export interface SettingsToggleButtonConfig extends ToggleButtonConfig { /** * The settings panel whose visibility the button should toggle. */ settingsPanel: SettingsPanel<SettingsPanelConfig>; /** * Decides if the button should be automatically hidden when the settings panel does not contain any active settings. * Default: true */ autoHideWhenNoActiveSettings?: boolean; } /** * A button that toggles visibility of a settings panel. * * @category Buttons */ export class SettingsToggleButton extends ToggleButton<SettingsToggleButtonConfig> { private visibleSettingsPanels: SettingsPanel<SettingsPanelConfig>[] = []; constructor(config: SettingsToggleButtonConfig) { super(config); if (!config.settingsPanel) { throw new Error('Required SettingsPanel is missing'); } this.config = this.mergeConfig( config, { cssClass: 'ui-settingstogglebutton', text: i18n.getLocalizer('settings'), settingsPanel: null, autoHideWhenNoActiveSettings: true, role: 'pop-up button', }, <SettingsToggleButtonConfig>this.config, ); /** * WCAG20 standard defines which popup menu (element id) is owned by the button */ this.getDomElement().attr('aria-owns', config.settingsPanel.getActivePage().getConfig().id); /** * WCAG20 standard defines that a button has a popup menu bound to it */ this.getDomElement().attr('aria-haspopup', 'true'); } configure(player: PlayerAPI, uimanager: UIInstanceManager): void { super.configure(player, uimanager); const config = this.getConfig(); const settingsPanel = config.settingsPanel; this.onClick.subscribe(() => { // only hide other `SettingsPanel`s if a new one will be opened if (!settingsPanel.isShown()) { // Hide all open SettingsPanels before opening this button's panel // (We need to iterate a copy because hiding them will automatically remove themselves from the array // due to the subscribeOnce above) this.visibleSettingsPanels.slice().forEach(settingsPanel => settingsPanel.hide()); } settingsPanel.toggleHidden(); }); settingsPanel.onShow.subscribe(() => { // Set toggle status to on when the settings panel shows this.on(); }); settingsPanel.onHide.subscribe(() => { // Set toggle status to off when the settings panel hides this.off(); }); // Ensure that only one `SettingPanel` is visible at once // Keep track of shown SettingsPanels uimanager.onComponentShow.subscribe((sender: Component<ComponentConfig>) => { if (sender instanceof SettingsPanel) { this.visibleSettingsPanels.push(sender); sender.onHide.subscribeOnce(() => ArrayUtils.remove(this.visibleSettingsPanels, sender)); } }); // Handle automatic hiding of the button if there are no settings for the user to interact with if (config.autoHideWhenNoActiveSettings) { // Setup handler to show/hide button when the settings change const settingsPanelItemsChangedHandler = () => { if (settingsPanel.rootPageHasActiveSettings()) { if (this.isHidden()) { this.show(); } } else { if (this.isShown()) { this.hide(); } } }; // Wire the handler to the event settingsPanel.onSettingsStateChanged.subscribe(settingsPanelItemsChangedHandler); // Call handler for first init at startup settingsPanelItemsChangedHandler(); } } }