UNPKG

@enact/sandstone

Version:

Large-screen/TV support library for Enact, containing a variety of UI components.

936 lines (931 loc) 38.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = exports.MediaControlsDecorator = exports.MediaControlsBase = exports.MediaControls = void 0; var _dispatcher = require("@enact/core/dispatcher"); var _handle = require("@enact/core/handle"); var _kind = _interopRequireDefault(require("@enact/core/kind")); var _hoc = _interopRequireDefault(require("@enact/core/hoc")); var _keymap = require("@enact/core/keymap"); var _util = require("@enact/core/util"); var _ApiDecorator = _interopRequireDefault(require("@enact/core/internal/ApiDecorator")); var _propTypes = _interopRequireDefault(require("@enact/core/internal/prop-types")); var _spotlight = _interopRequireDefault(require("@enact/spotlight")); var _Pause = _interopRequireDefault(require("@enact/spotlight/Pause")); var _SpotlightContainerDecorator = require("@enact/spotlight/SpotlightContainerDecorator"); var _Cancelable = _interopRequireDefault(require("@enact/ui/Cancelable")); var _Slottable = _interopRequireDefault(require("@enact/ui/Slottable")); var _propTypes2 = _interopRequireDefault(require("prop-types")); var _react = require("react"); var _ActionGuide = _interopRequireDefault(require("../ActionGuide")); var _Button = _interopRequireDefault(require("../Button")); var _$L = _interopRequireDefault(require("../internal/$L")); var _util2 = require("../internal/util"); var _Skinnable = _interopRequireDefault(require("../Skinnable")); var _util3 = require("./util"); var _MediaControlsModule = _interopRequireDefault(require("./MediaControls.module.css")); var _jsxRuntime = require("react/jsx-runtime"); var _excluded = ["mediaControlsRef"], _excluded2 = ["actionGuideAriaLabel", "actionGuideButtonAriaLabel", "actionGuideDisabled", "actionGuideLabel", "actionGuideShowing", "children", "id", "jumpBackwardAriaLabel", "jumpBackwardIcon", "jumpButtonsDisabled", "jumpForwardAriaLabel", "jumpForwardIcon", "bottomComponents", "mediaControlsRef", "mediaDisabled", "moreComponentsSpotlightId", "noJumpButtons", "onActionGuideClick", "onJumpBackwardButtonClick", "onJumpForwardButtonClick", "onKeyDownFromMediaButtons", "onPlayButtonClick", "paused", "pauseIcon", "playIcon", "playPauseButtonDisabled", "showMoreComponents", "moreComponentsRendered", "moreButtonsClassName", "moreComponentsClassName", "actionGuideClassName", "spotlightDisabled", "spotlightId"]; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } var DivComponent = function DivComponent(_ref) { var mediaControlsRef = _ref.mediaControlsRef, rest = _objectWithoutProperties(_ref, _excluded); return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", _objectSpread({ ref: mediaControlsRef }, rest)); }; DivComponent.propTypes = { /* * Called with the reference to the mediaControls node. * * @type {Object|Function} * @public */ mediaControlsRef: _propTypes["default"].ref }; var OuterContainer = (0, _SpotlightContainerDecorator.SpotlightContainerDecorator)({ defaultElement: [".".concat(_SpotlightContainerDecorator.spotlightDefaultClass)], leaveFor: { left: '', right: '' } }, DivComponent); var Container = (0, _SpotlightContainerDecorator.SpotlightContainerDecorator)({ enterTo: 'default-element' }, 'div'); var MediaButton = (0, _util2.onlyUpdateForProps)(_Button["default"], ['children', 'className', 'disabled', 'icon', 'onClick', 'spotlightDisabled']); var forwardToggleMore = (0, _handle.forward)('onToggleMore'); var animationDuration = 300; /** * A set of components for controlling media playback and rendering additional components. * * @class MediaControlsBase * @memberof sandstone/MediaPlayer * @ui * @private */ var MediaControlsBase = exports.MediaControlsBase = (0, _kind["default"])({ name: 'MediaControls', // intentionally assigning these props to MediaControls instead of Base (which is private) propTypes: /** @lends sandstone/MediaPlayer.MediaControls.prototype */{ /** * DOM id for the component. * * This child component `ActionGuide`'s id is generated from the id. * * @type {String} * @required * @public */ id: _propTypes2["default"].string.isRequired, /** * The `aria-label` for the action guide. * * @type {String} * @public */ actionGuideAriaLabel: _propTypes2["default"].string, /** * The `aria-label` for the action guide button. * * @type {String} * @public */ actionGuideButtonAriaLabel: _propTypes2["default"].string, /** * Disables the ActionGuide. * * @type {Boolean} * @public */ actionGuideDisabled: _propTypes2["default"].bool, /** * The label for the action guide. * * @type {String} * @public */ actionGuideLabel: _propTypes2["default"].string, /** * These components are placed below the action guide. Typically these will be media playlist controls. * * @type {Node} * @public */ bottomComponents: _propTypes2["default"].node, /** * The `aria-label` for the jumpBackward button. * * @type {String} * @public */ jumpBackwardAriaLabel: _propTypes2["default"].string, /** * Jump backward {@link sandstone/Icon.Icon|icon} name. Accepts any * {@link sandstone/Icon.Icon|icon} component type. * * @type {String} * @default 'jumpbackward' * @public */ jumpBackwardIcon: _propTypes2["default"].string, /** * Disables state on the media "jump" buttons; the outer pair. * * @type {Boolean} * @public */ jumpButtonsDisabled: _propTypes2["default"].bool, /** * The `aria-label` for the jumpForward button. * * @type {String} * @public */ jumpForwardAriaLabel: _propTypes2["default"].string, /** * Jump forward {@link sandstone/Icon.Icon|icon} name. Accepts any * {@link sandstone/Icon.Icon|icon} component type. * * @type {String} * @default 'jumpforward' * @public */ jumpForwardIcon: _propTypes2["default"].string, /** * Called with the reference to the mediaControls node. * * @type {Object|Function} * @public */ mediaControlsRef: _propTypes["default"].ref, /** * Disables the media buttons. * * @type {Boolean} * @public */ mediaDisabled: _propTypes2["default"].bool, /** * When `true`, more components are rendered. This does not indicate the visibility of more components. * * @type {Boolean} * @public */ moreComponentsRendered: _propTypes2["default"].bool, /** * The spotlight ID for the moreComponent container. * * @type {String} * @public * @default 'moreComponents' */ moreComponentsSpotlightId: _propTypes2["default"].string, /** * Removes the "jump" buttons. The buttons that skip forward or backward in the video. * * @type {Boolean} * @public */ noJumpButtons: _propTypes2["default"].bool, /** * Called when the button in ActionGuide is clicked. * * @type {Function} * @param {Object} event * @public */ onActionGuideClick: _propTypes2["default"].func, /** * Called when cancel/back key events are fired. * * @type {Function} * @public */ onClose: _propTypes2["default"].func, /** * Called when the user clicks the JumpBackward button * * @type {Function} * @public */ onJumpBackwardButtonClick: _propTypes2["default"].func, /** * Called when the user clicks the JumpForward button. * * @type {Function} * @public */ onJumpForwardButtonClick: _propTypes2["default"].func, /** * Called when the user presses a media control button. * * @type {Function} * @public */ onKeyDownFromMediaButtons: _propTypes2["default"].func, /** * Called when the user clicks the Play button. * * @type {Function} * @public */ onPlayButtonClick: _propTypes2["default"].func, /** * `true` when the video is paused. * * @type {Boolean} * @public */ paused: _propTypes2["default"].bool, /** * A string which is sent to the `pause` icon of the player controls. This can be * anything that is accepted by {@link sandstone/Icon.Icon|Icon}. This will be temporarily replaced by * the {@link sandstone/MediaPlayer.MediaControls.playIcon|playIcon} when the * {@link sandstone/MediaPlayer.MediaControls.paused|paused} boolean is `false`. * * @type {String} * @default 'pause' * @public */ pauseIcon: _propTypes2["default"].string, /** * A string which is sent to the `play` icon of the player controls. This can be * anything that is accepted by {@link sandstone/Icon.Icon}. This will be temporarily replaced by * the {@link sandstone/MediaPlayer.MediaControls.pauseIcon|pauseIcon} when the * {@link sandstone/MediaPlayer.MediaControls.paused|paused} boolean is `true`. * * @type {String} * @default 'play' * @public */ playIcon: _propTypes2["default"].string, /** * Disables the media "play"/"pause" button. * * @type {Boolean} * @public */ playPauseButtonDisabled: _propTypes2["default"].bool, /** * When `true`, more components are visible. * * @type {Boolean} * @private */ showMoreComponents: _propTypes2["default"].bool, /** * `true` controls are disabled from Spotlight. * * @type {Boolean} * @public */ spotlightDisabled: _propTypes2["default"].bool, /** * The spotlight ID for the media controls container. * * @type {String} * @public * @default 'mediaControls' */ spotlightId: _propTypes2["default"].string, /** * The visibility of the component. When `false`, the component will be hidden. * * @type {Boolean} * @default true * @public */ visible: _propTypes2["default"].bool }, defaultProps: { jumpBackwardIcon: 'jumpbackward', jumpForwardIcon: 'jumpforward', moreComponentsSpotlightId: 'moreComponents', spotlightId: 'mediaControls', pauseIcon: 'pause', playIcon: 'play', visible: true }, styles: { css: _MediaControlsModule["default"], className: 'controlsFrame' }, computed: { actionGuideClassName: function actionGuideClassName(_ref2) { var styler = _ref2.styler, showMoreComponents = _ref2.showMoreComponents; return styler.join({ hidden: showMoreComponents }); }, actionGuideShowing: function actionGuideShowing(_ref3) { var bottomComponents = _ref3.bottomComponents, children = _ref3.children; return (0, _util3.countReactChildren)(children) || bottomComponents; }, className: function className(_ref4) { var visible = _ref4.visible, styler = _ref4.styler; return styler.append({ hidden: !visible }); }, moreButtonsClassName: function moreButtonsClassName(_ref5) { var styler = _ref5.styler; return styler.join('mediaControls', 'moreButtonsComponents'); }, moreComponentsClassName: function moreComponentsClassName(_ref6) { var styler = _ref6.styler, showMoreComponents = _ref6.showMoreComponents; return styler.join({ hidden: !showMoreComponents }, 'moreComponents'); }, moreComponentsRendered: function moreComponentsRendered(_ref7) { var showMoreComponents = _ref7.showMoreComponents, _moreComponentsRendered = _ref7.moreComponentsRendered; return showMoreComponents || _moreComponentsRendered; } }, render: function render(_ref8) { var actionGuideAriaLabel = _ref8.actionGuideAriaLabel, actionGuideButtonAriaLabel = _ref8.actionGuideButtonAriaLabel, actionGuideDisabled = _ref8.actionGuideDisabled, actionGuideLabel = _ref8.actionGuideLabel, actionGuideShowing = _ref8.actionGuideShowing, children = _ref8.children, id = _ref8.id, jumpBackwardAriaLabel = _ref8.jumpBackwardAriaLabel, jumpBackwardIcon = _ref8.jumpBackwardIcon, jumpButtonsDisabled = _ref8.jumpButtonsDisabled, jumpForwardAriaLabel = _ref8.jumpForwardAriaLabel, jumpForwardIcon = _ref8.jumpForwardIcon, bottomComponents = _ref8.bottomComponents, mediaControlsRef = _ref8.mediaControlsRef, mediaDisabled = _ref8.mediaDisabled, moreComponentsSpotlightId = _ref8.moreComponentsSpotlightId, noJumpButtons = _ref8.noJumpButtons, onActionGuideClick = _ref8.onActionGuideClick, onJumpBackwardButtonClick = _ref8.onJumpBackwardButtonClick, onJumpForwardButtonClick = _ref8.onJumpForwardButtonClick, onKeyDownFromMediaButtons = _ref8.onKeyDownFromMediaButtons, onPlayButtonClick = _ref8.onPlayButtonClick, paused = _ref8.paused, pauseIcon = _ref8.pauseIcon, playIcon = _ref8.playIcon, playPauseButtonDisabled = _ref8.playPauseButtonDisabled, showMoreComponents = _ref8.showMoreComponents, moreComponentsRendered = _ref8.moreComponentsRendered, moreButtonsClassName = _ref8.moreButtonsClassName, moreComponentsClassName = _ref8.moreComponentsClassName, actionGuideClassName = _ref8.actionGuideClassName, spotlightDisabled = _ref8.spotlightDisabled, spotlightId = _ref8.spotlightId, rest = _objectWithoutProperties(_ref8, _excluded2); delete rest.onClose; delete rest.visible; return /*#__PURE__*/(0, _jsxRuntime.jsxs)(OuterContainer, _objectSpread(_objectSpread({}, rest), {}, { id: id, mediaControlsRef: mediaControlsRef, spotlightId: spotlightId, children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(Container, { className: _MediaControlsModule["default"].mediaControls, spotlightDisabled: spotlightDisabled, onKeyDown: onKeyDownFromMediaButtons, children: [noJumpButtons ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(MediaButton, { "aria-label": jumpBackwardAriaLabel || (0, _$L["default"])('Previous'), backgroundOpacity: "transparent", css: _MediaControlsModule["default"], disabled: mediaDisabled || jumpButtonsDisabled, icon: jumpBackwardIcon, onClick: onJumpBackwardButtonClick, size: "large", spotlightDisabled: spotlightDisabled }), /*#__PURE__*/(0, _jsxRuntime.jsx)(MediaButton, { "aria-label": paused ? (0, _$L["default"])('Play') : (0, _$L["default"])('Pause'), className: _SpotlightContainerDecorator.spotlightDefaultClass, backgroundOpacity: "transparent", css: _MediaControlsModule["default"], disabled: mediaDisabled || playPauseButtonDisabled, icon: paused ? playIcon : pauseIcon, onClick: onPlayButtonClick, size: "large", spotlightDisabled: spotlightDisabled }), noJumpButtons ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(MediaButton, { "aria-label": jumpForwardAriaLabel || (0, _$L["default"])('Next'), backgroundOpacity: "transparent", css: _MediaControlsModule["default"], disabled: mediaDisabled || jumpButtonsDisabled, icon: jumpForwardIcon, onClick: onJumpForwardButtonClick, size: "large", spotlightDisabled: spotlightDisabled })] }), actionGuideShowing ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_ActionGuide["default"], { id: "".concat(id, "_actionGuide"), "aria-label": actionGuideAriaLabel != null ? actionGuideAriaLabel : null, buttonAriaLabel: actionGuideButtonAriaLabel, css: _MediaControlsModule["default"], className: actionGuideClassName, icon: "arrowsmalldown", onClick: onActionGuideClick, disabled: actionGuideDisabled, children: actionGuideLabel }) : null, moreComponentsRendered ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(Container, { spotlightId: moreComponentsSpotlightId, className: moreComponentsClassName, spotlightDisabled: !showMoreComponents || spotlightDisabled, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(Container, { className: moreButtonsClassName, children: children }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", { children: bottomComponents })] }) : null] })); } }); /** * Media control behaviors to apply to {@link sandstone/MediaPlayer.MediaControlsBase|MediaControlsBase}. * Provides built-in support for showing more components and key handling for basic playback * controls. * * @class MediaControlsDecorator * @memberof sandstone/MediaPlayer * @mixes ui/Slottable.Slottable * @hoc * @private */ var MediaControlsDecorator = exports.MediaControlsDecorator = (0, _hoc["default"])(function (config, Wrapped) { var MediaControlsDecoratorHOC = /*#__PURE__*/function (_Component) { _inherits(MediaControlsDecoratorHOC, _Component); var _super = _createSuper(MediaControlsDecoratorHOC); function MediaControlsDecoratorHOC(props) { var _this; _classCallCheck(this, MediaControlsDecoratorHOC); _this = _super.call(this, props); _this.moreComponentsRenderingJob = new _util.Job(function () { _this.setState({ moreComponentsRendered: true }); }); _this.calculateMoreComponentsHeight = function () { if (!_this.mediaControlsNode) { _this.bottomComponentsHeight = 0; return; } var bottomElement = _this.mediaControlsNode.querySelector(".".concat(_MediaControlsModule["default"].moreComponents)); _this.bottomComponentsHeight = bottomElement ? bottomElement.scrollHeight : 0; }; _this.handleKeyDown = function (ev) { var _this$props = _this.props, mediaDisabled = _this$props.mediaDisabled, no5WayJump = _this$props.no5WayJump, visible = _this$props.visible; var current = _spotlight["default"].getCurrent(); if (!no5WayJump && !visible && !mediaDisabled && !current && ((0, _keymap.is)('left', ev.keyCode) || (0, _keymap.is)('right', ev.keyCode))) { _this.paused.pause(); _this.startListeningForPulses(ev.keyCode); } }; _this.handleKeyUp = function (ev) { var _this$props2 = _this.props, mediaDisabled = _this$props2.mediaDisabled, no5WayJump = _this$props2.no5WayJump, rateChangeDisabled = _this$props2.rateChangeDisabled, playPauseButtonDisabled = _this$props2.playPauseButtonDisabled; if (mediaDisabled) return; if (!playPauseButtonDisabled) { if ((0, _keymap.is)('play', ev.keyCode)) { (0, _handle.forward)('onPlay', ev, _this.props); } else if ((0, _keymap.is)('pause', ev.keyCode)) { (0, _handle.forward)('onPause', ev, _this.props); } } if (!no5WayJump && ((0, _keymap.is)('left', ev.keyCode) || (0, _keymap.is)('right', ev.keyCode))) { _this.stopListeningForPulses(); _this.paused.resume(); } if (!rateChangeDisabled) { if ((0, _keymap.is)('rewind', ev.keyCode)) { (0, _handle.forward)('onRewind', ev, _this.props); } else if ((0, _keymap.is)('fastForward', ev.keyCode)) { (0, _handle.forward)('onFastForward', ev, _this.props); } } }; _this.handleBlur = function () { _this.stopListeningForPulses(); _this.paused.resume(); }; _this.handleActionGuideClick = function () { if (!_this.state.showMoreComponents) { _this.showMoreComponents(); } }; _this.startListeningForPulses = function (keyCode) { // Ignore new pulse calls if key code is same, otherwise start new series if we're pulsing if (_this.pulsing && keyCode !== _this.pulsingKeyCode) { _this.stopListeningForPulses(); } if (!_this.pulsing) { _this.pulsingKeyCode = keyCode; _this.pulsing = true; _this.keyLoop = setTimeout(_this.handlePulse, _this.props.initialJumpDelay); (0, _handle.forward)('onJump', { keyCode: keyCode }, _this.props); } }; _this.handlePulse = function () { (0, _handle.forward)('onJump', { keyCode: _this.pulsingKeyCode }, _this.props); _this.keyLoop = setTimeout(_this.handlePulse, _this.props.jumpDelay); }; _this.handlePlayButtonClick = function (ev) { (0, _handle.forward)('onPlayButtonClick', ev, _this.props); if (_this.props.paused) { (0, _handle.forward)('onPlay', ev, _this.props); } else { (0, _handle.forward)('onPause', ev, _this.props); } }; _this.getMediaControls = function (node) { if (!node) { _this.actionGuideHeight = 0; return; } _this.mediaControlsNode = _this.mediaControlsRef.current; var guideElement = _this.mediaControlsNode.querySelector(".".concat(_MediaControlsModule["default"].actionGuide)); _this.actionGuideHeight = guideElement ? guideElement.scrollHeight : 0; }; _this.areMoreComponentsAvailable = function () { return _this.state.showMoreComponents; }; _this.showMoreComponents = function () { _this.setState({ showMoreComponents: true }); }; _this.hideMoreComponents = function () { _this.setState({ showMoreComponents: false }); }; _this.handleClose = function (ev) { if (_this.props.visible) { (0, _handle.forward)('onClose', ev, _this.props); } }; _this.handleFinish = function () { if (_this.state.showMoreComponents) { _this.paused.resume(); if (!_spotlight["default"].getPointerMode()) { _spotlight["default"].focus(_this.moreComponentsSpotlightId); } } }; _this.handleCancel = function () { _this.paused.resume(); }; _this.mediaControlsNode = null; _this.moreComponentsNode = null; _this.actionGuideHeight = 0; _this.animation = null; _this.bottomComponentsHeight = 0; _this.moreComponentsSpotlightId = 'moreComponents'; _this.keyLoop = null; _this.pulsingKeyCode = null; _this.pulsing = null; _this.paused = new _Pause["default"]('MediaPlayer'); _this.mediaControlsRef = /*#__PURE__*/(0, _react.createRef)(); _this.state = { showMoreComponents: false, moreComponentsRendered: false }; if (props.setApiProvider) { props.setApiProvider(_assertThisInitialized(_this)); } return _this; } _createClass(MediaControlsDecoratorHOC, [{ key: "componentDidMount", value: function componentDidMount() { (0, _dispatcher.on)('keydown', this.handleKeyDown, document); (0, _dispatcher.on)('keyup', this.handleKeyUp, document); (0, _dispatcher.on)('blur', this.handleBlur, window); } }, { key: "componentDidUpdate", value: function componentDidUpdate(prevProps, prevState) { // Need to render `moreComponents` to show it. For performance, render `moreComponents` if it is actually shown. if (!prevState.showMoreComponents && this.state.showMoreComponents && !this.state.moreComponentsRendered) { this.moreComponentsRenderingJob.startRafAfter(); } else if (prevState.showMoreComponents && !this.state.showMoreComponents) { this.moreComponentsRenderingJob.stop(); } if (!prevState.moreComponentsRendered && this.state.moreComponentsRendered || this.state.moreComponentsRendered && prevProps.bottomComponents !== this.props.bottomComponents || !(0, _util2.compareChildren)(this.props.children, prevProps.children)) { this.calculateMoreComponentsHeight(); } if (this.state.showMoreComponents && !prevState.moreComponentsRendered && this.state.moreComponentsRendered || this.state.moreComponentsRendered && prevState.showMoreComponents !== this.state.showMoreComponents) { forwardToggleMore({ type: 'onToggleMore', showMoreComponents: this.state.showMoreComponents, liftDistance: this.bottomComponentsHeight - this.actionGuideHeight }, this.props); if (this.state.showMoreComponents) { this.moreComponentsNode = this.moreComponentsNode || this.mediaControlsNode.querySelector(".".concat(_MediaControlsModule["default"].moreComponents)); this.paused.pause(); this.animation = this.moreComponentsNode.animate([{ transform: 'none', opacity: 0, offset: 0 }, { transform: "translateY(".concat(-this.actionGuideHeight, "px)"), opacity: 1, offset: 1 }], { duration: animationDuration, fill: 'forwards' }); this.animation.onfinish = this.handleFinish; this.animation.oncancel = this.handleCancel; } else if (this.animation != null) { this.animation.cancel(); } } // if media controls disabled, reset key loop if (!prevProps.mediaDisabled && this.props.mediaDisabled || !prevProps.visible && this.props.visible) { this.stopListeningForPulses(); this.paused.resume(); } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { (0, _dispatcher.off)('keydown', this.handleKeyDown, document); (0, _dispatcher.off)('keyup', this.handleKeyUp, document); (0, _dispatcher.off)('blur', this.handleBlur, window); this.stopListeningForPulses(); this.moreComponentsRenderingJob.stop(); if (this.animation) { this.animation.cancel(); } } }, { key: "stopListeningForPulses", value: function stopListeningForPulses() { this.pulsing = false; if (this.keyLoop) { clearTimeout(this.keyLoop); this.keyLoop = null; } } }, { key: "toggleMoreComponents", value: function toggleMoreComponents() { this.setState(function (prevState) { return { showMoreComponents: !prevState.showMoreComponents }; }); } }, { key: "render", value: function render() { var props = Object.assign({}, this.props); delete props.initialJumpDelay; delete props.jumpDelay; delete props.moreActionDisabled; delete props.no5WayJump; delete props.onFastForward; delete props.onJump; delete props.onPause; delete props.onPlay; delete props.onRewind; delete props.onToggleMore; delete props.rateChangeDisabled; delete props.setApiProvider; return /*#__PURE__*/(0, _jsxRuntime.jsx)(Wrapped, _objectSpread(_objectSpread({}, props), {}, { mediaControlsRef: this.mediaControlsRef, actionGuideDisabled: this.props.moreActionDisabled, moreComponentsRendered: this.state.moreComponentsRendered, moreComponentsSpotlightId: this.moreComponentsSpotlightId, onActionGuideClick: this.handleActionGuideClick, onClose: this.handleClose, onPlayButtonClick: this.handlePlayButtonClick, ref: this.getMediaControls, showMoreComponents: this.state.showMoreComponents })); } }], [{ key: "getDerivedStateFromProps", value: function getDerivedStateFromProps(props) { if (!props.visible) { return { showMoreComponents: false }; } return null; } }]); return MediaControlsDecoratorHOC; }(_react.Component); MediaControlsDecoratorHOC.displayName = 'MediaControlsDecorator'; MediaControlsDecoratorHOC.propTypes = /** @lends sandstone/MediaPlayer.MediaControlsDecorator.prototype */{ /** * The label for the action guide. * * @type {String} * @public */ actionGuideLabel: _propTypes2["default"].string, /** * These components are placed below the children. Typically these will be media playlist items. * * @type {Node} * @public */ bottomComponents: _propTypes2["default"].node, /** * The number of milliseconds that the player will pause before firing the * first jump event on a right or left pulse. * * @type {Number} * @default 400 * @public */ initialJumpDelay: _propTypes2["default"].number, /** * The number of milliseconds that the player will throttle before firing a * jump event on a right or left pulse. * * @type {Number} * @default 200 * @public */ jumpDelay: _propTypes2["default"].number, /** * Disables the media buttons. * * @type {Boolean} * @public */ mediaDisabled: _propTypes2["default"].bool, /** * Disables showing more components. * * @type {Boolean} * @public */ moreActionDisabled: _propTypes2["default"].bool, /** * Setting this to `true` will disable left and right keys for seeking. * * @type {Boolean} * @public */ no5WayJump: _propTypes2["default"].bool, /** * Called when media fast forwards. * * @type {Function} * @public */ onFastForward: _propTypes2["default"].func, /** * Called when media jumps. * * @type {Function} * @public */ onJump: _propTypes2["default"].func, /** * Called when media gets paused. * * @type {Function} * @public */ onPause: _propTypes2["default"].func, /** * Called when media starts playing. * * @type {Function} * @public */ onPlay: _propTypes2["default"].func, /** * Called when media rewinds. * * @type {Function} * @public */ onRewind: _propTypes2["default"].func, /** * Called when the visibility of more components is changed * * Event payload includes: * * * `type` - Type of event, `'onToggleMore'` * * `showMoreComponents` - `true` when the components are visible` * * `liftDistance` - The distance, in pixels, the component animates * * @type {Function} * @public */ onToggleMore: _propTypes2["default"].func, /** * The video pause state. * * @type {Boolean} * @public */ paused: _propTypes2["default"].bool, /** * Disables state on the media "play"/"pause" button * * @type {Boolean} * @public */ playPauseButtonDisabled: _propTypes2["default"].bool, /** * Disables the media playback-rate control via rewind and fast forward keys * * @type {Boolean} * @public */ rateChangeDisabled: _propTypes2["default"].bool, /** * Registers the MediaControls component with an * {@link core/internal/ApiDecorator.ApiDecorator|ApiDecorator}. * * @type {Function} * @private */ setApiProvider: _propTypes2["default"].func, /** * The visibility of the component. When `false`, the component will be hidden. * * @type {Boolean} * @public */ visible: _propTypes2["default"].bool }; MediaControlsDecoratorHOC.defaultProps = { initialJumpDelay: 400, jumpDelay: 200 }; return (0, _Slottable["default"])({ slots: ['bottomComponents'] }, MediaControlsDecoratorHOC); }); var handleCancel = function handleCancel(ev, _ref9) { var onClose = _ref9.onClose; if (onClose) { onClose(ev); } }; /** * A set of components for controlling media playback and rendering additional components. * * This uses {@link ui/Slottable|Slottable} to accept the custom tags, `<bottomComponents>` * to add components to the bottom of the media controls. Any additional children will be * rendered into the "more" controls area. Showing the additional components is handled by * `MediaControls` when the user navigates down from the media buttons. * * @class MediaControls * @memberof sandstone/MediaPlayer * @mixes ui/Cancelable.Cancelable * @mixes sandstone/Skinnable.Skinnable * @ui * @public */ var MediaControls = exports.MediaControls = (0, _ApiDecorator["default"])({ api: ['areMoreComponentsAvailable', 'showMoreComponents', 'hideMoreComponents'] }, MediaControlsDecorator((0, _Cancelable["default"])({ modal: true, onCancel: handleCancel }, (0, _Skinnable["default"])(MediaControlsBase)))); MediaControls.defaultSlot = 'mediaControlsComponent'; var _default = exports["default"] = MediaControls;