Files
_hublib-web/dist/core/plugins/settings/index.js
2026-02-27 09:50:13 +03:00

141 lines
6.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import videojs from "video.js";
import TachVideoMenuButton from "./components/tach-video-menu-button";
import TachVideoMenuItem from "./components/tach-video-menu-item";
import audioTrackSelector from "./selectors/audio-track-selector";
import playbackRateSelector from "./selectors/playback-rate-selector";
import qualityRateSelector from "./selectors/quality-rate-selector";
import textTracksSelector from "./selectors/text-track-selector";
import "./settings.css";
const BasePlugin = videojs.getPlugin("plugin");
// Значения опций по умолчанию
const defaults = {};
class SettingsButton extends BasePlugin {
constructor(player, options) {
super(player);
this.mainMenu = [];
this.options = videojs.obj.merge(defaults, options);
this.player.ready(() => this.initialize());
}
/**
* Инициализация плагина: создание кнопки настроек и привязка событий
*/
initialize() {
this.createSettingsButton();
this.bindPlayerEvents();
}
/**
* Привязка событий плеера (например, для обновления меню)
*/
bindPlayerEvents() {
// При необходимости можно привязать событие, например:
// this.settingsButton.on("click", this.setMenu.bind(this, undefined, false, true));
}
/**
* Создание кнопки настроек и определение пунктов меню.
* Здесь создаются фабрики для формирования кнопок и устанавливается начальное меню.
*/
createSettingsButton() {
const player = this.player;
// Создаем кнопку настроек с помощью компонента TachVideoMenuButton
this.settingsButton = new TachVideoMenuButton(player, "Settings", "Settings");
this.buttonInstance = player.controlBar.addChild(this.settingsButton, {
componentClass: "settingsButton",
});
this.buttonInstance.addClass("vjs-settings-button");
// Определяем кнопку "Назад" для возврата в главное меню
this.backButton = {
label: "Назад",
value: this.mainMenu,
selectable: false,
selected: false,
onClick: () => this.setMenu(undefined, true, true),
className: "settings-back",
};
// Создаем фабрики для дополнительных настроек
const { menuItem: audioMenuItem, menuItems: audioMenuItems } = audioTrackSelector(player);
this.audioTracksButton = () => ({
...audioMenuItem(),
onClick: () => this.setMenu(audioMenuItems(), false, true),
});
const { menuItem: textMenuItem, menuItems: textMenuItems } = textTracksSelector(player);
this.textTracksButton = () => ({
...textMenuItem(),
onClick: () => this.setMenu(textMenuItems(), false, true),
});
const { menuItem: playbackMenuItem, menuItems: playbackMenuItems } = playbackRateSelector(player);
this.playbackRateButton = () => ({
...playbackMenuItem(),
onClick: () => this.setMenu(playbackMenuItems(), false, true),
});
// В createSettingsButton замени этот участок:
const qualitySelector = qualityRateSelector(player);
this.qualityRateButton = () => ({
...qualitySelector.menuItem(), // пересоздание при каждом открытии меню
onClick: () => this.setMenu(qualitySelector.menuItems(), false, true),
});
// Подписка на автообновление, когда hls переключает уровень
qualitySelector.setMenuUpdateCallback(() => {
this.setMenu(undefined, true); // Обновить главное меню без перезахода
});
// Инициализируем меню с кнопками по умолчанию без показа
this.setMenu(undefined, true, false);
}
/**
* Обёртка для создания экземпляра пункта меню.
*
* @param item - объект настроек пункта меню
* @returns экземпляр TachVideoMenuItem
*/
getMenuItem(item) {
return new TachVideoMenuItem(this.player, item, this.settingsButton, this);
}
/**
* Устанавливает (обновляет) пункты меню плагина.
*
* @param items - массив пунктов меню (если не передан, используются кнопки по умолчанию)
* @param skipBackButton - если true, не добавлять кнопку "Назад"
* @param forceShow - если true, принудительно показать меню после обновления
*/
async setMenu(items = [], skipBackButton = false, forceShow = false) {
const menuButtons = [];
if (!skipBackButton) {
menuButtons.push(this.backButton);
}
if (items?.length === 0) {
// Если не переданы конкретные пункты меню используем кнопки по умолчанию
const defaultButtons = [
this.playbackRateButton,
this.qualityRateButton,
this.textTracksButton,
this.audioTracksButton,
];
defaultButtons.forEach(createButton => {
const btn = createButton();
if (btn.enabled) {
menuButtons.push(btn);
}
});
}
else {
menuButtons.push(...items);
}
// Формируем список пунктов меню: вместо пересоздания меню, назначаем функцию,
// возвращающую актуальный список пунктов, и вызываем метод обновления.
this.settingsButton.createItems = () => menuButtons.map(item => this.getMenuItem(item));
await this.settingsButton.update();
// Если требуется принудительно показать меню, эмулируем клик по кнопке меню
if (forceShow) {
const menuElement = this.buttonInstance.el().querySelector(".vjs-menu");
const menuButton = this.buttonInstance
.el()
.querySelector(".vjs-menu-button");
if (menuElement && menuButton) {
menuButton.click();
}
}
}
}
// Регистрируем плагин в Video.js
videojs.registerPlugin("settingsMenu", SettingsButton);
export default SettingsButton;
//# sourceMappingURL=index.js.map