custom-react-player
Version:
Customizable react video player
404 lines (375 loc) • 40.1 kB
JavaScript
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
import { createContext, useState, useContext, useEffect, useRef, useLayoutEffect } from 'react';
import styled from 'styled-components';
import { motion } from 'framer-motion';
import screenfull from 'screenfull';
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol */
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __makeTemplateObject(cooked, raw) {
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
return cooked;
}
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
var DefaultPlayerState = {
state: {
accentColor: 'orange',
currentVolume: 1,
duration: 0,
isFullscreen: false,
playing: false,
previousVolume: 0,
volumeSliderOpen: false,
viewportWidth: 0,
viewportHeight: 0,
},
// eslint-disable-next-line @typescript-eslint/no-empty-function
setState: function () { },
};
var PContext = createContext(DefaultPlayerState);
function PlayerContextProvider(_a) {
var state = _a.state, children = _a.children;
var _b = useState(state), playerState = _b[0], setPlayerState = _b[1];
return (jsx(PContext.Provider, __assign({ value: {
state: playerState,
setState: setPlayerState,
} }, { children: children })));
}
var usePlayerContext = (useContext);
function PlayerControls(_a) {
var children = _a.children, playerRef = _a.playerRef, wrapperRef = _a.wrapperRef;
var videoEl = playerRef === null || playerRef === void 0 ? void 0 : playerRef.current;
var _b = usePlayerContext(PContext), state = _b.state, setState = _b.setState;
var _c = useState(false), mouseActive = _c[0], setMouseActive = _c[1];
var _d = useState({
height: state.viewportHeight,
width: state.viewportWidth,
}), videoDimensions = _d[0], setVideoDimensions = _d[1];
// EVENT (mousemove): handling animating controls in/out
useEffect(function () {
var timeoutId;
var handleMouseMove = function () {
setMouseActive(true);
clearTimeout(timeoutId);
timeoutId = setTimeout(function () { return setMouseActive(false); }, 2000);
};
document.body.addEventListener('mousemove', handleMouseMove);
return function () {
document.removeEventListener('mousemove', handleMouseMove);
clearTimeout(timeoutId);
};
}, []);
// EVENT (resize): handling reszing viewport
useEffect(function () {
if (!videoEl)
return;
var handleResize = function () { return setDimensions(videoEl); };
handleResize();
window.addEventListener('resize', handleResize);
return function () { return window.removeEventListener('resize', handleResize); };
}, [videoEl]);
useEffect(function () {
setVideoDimensions({
height: state.viewportHeight,
width: state.viewportWidth,
});
}, [state.viewportHeight, state.viewportWidth]);
var setDimensions = function (el) {
setState(function (prev) { return (__assign(__assign({}, prev), { viewportHeight: el.clientHeight, viewportWidth: el.clientWidth })); });
};
if (!videoEl || !wrapperRef) {
return jsx(Fragment, {});
}
return (jsx(Wrapper$6, __assign({ animate: {
background: mouseActive
? 'linear-gradient(0deg,rgba(0, 0, 0, 0.65) 0%,rgba(0, 0, 0, 0) 30%, rgba(0, 0, 0, 0) 70%,rgba(0, 0, 0, 0.65) 100%)'
: '',
opacity: mouseActive ? 1 : 0,
}, "$dimensions": videoDimensions, className: 'playerControls' }, { children: children })));
}
var Wrapper$6 = styled(motion.div)(templateObject_1$8 || (templateObject_1$8 = __makeTemplateObject(["\n height: ", "px;\n width: ", "px;\n flex-direction: column;\n align-items: center;\n position: absolute;\n display: flex;\n z-index: 10;\n"], ["\n height: ", "px;\n width: ", "px;\n flex-direction: column;\n align-items: center;\n position: absolute;\n display: flex;\n z-index: 10;\n"])), function (props) { return props.$dimensions.height; }, function (props) { return props.$dimensions.width; });
var templateObject_1$8;
var Icon = function (_a) {
var children = _a.children, _b = _a.height, height = _b === void 0 ? 32 : _b, _c = _a.width, width = _c === void 0 ? 32 : _c, viewbox = _a.viewbox, onClick = _a.onClick;
return (jsx(Svg, __assign({ viewBox: viewbox, width: width, height: height, version: '1.1', onClick: onClick }, { children: children })));
};
var Svg = styled.svg(templateObject_1$7 || (templateObject_1$7 = __makeTemplateObject(["\n cursor: pointer;\n"], ["\n cursor: pointer;\n"])));
var templateObject_1$7;
var PlayIcon = function (props) { return (jsx(Icon, __assign({}, props, { viewbox: '-5 0 28 28' }, { children: jsx("g", __assign({ stroke: 'none', strokeWidth: '1', fill: 'none', fillRule: 'evenodd' }, { children: jsx("g", __assign({ transform: 'translate(-419.000000, -571.000000)', fill: '#FFFFFF' }, { children: jsx("path", { d: 'M440.415,583.554 L421.418,571.311 C420.291,570.704 419,570.767 419,572.946 L419,597.054 C419,599.046 420.385,599.36 421.418,598.689 L440.415,586.446 C441.197,585.647 441.197,584.353 440.415,583.554', id: 'play' }) })) })) }))); };
var PauseIcon = function (props) { return (jsx(Icon, __assign({}, props, { viewbox: '0 0 24 24' }, { children: jsx("path", { fillRule: 'evenodd', clipRule: 'evenodd', d: 'M5.163 3.819C5 4.139 5 4.559 5 5.4v13.2c0 .84 0 1.26.163 1.581a1.5 1.5 0 0 0 .656.655c.32.164.74.164 1.581.164h.2c.84 0 1.26 0 1.581-.163a1.5 1.5 0 0 0 .656-.656c.163-.32.163-.74.163-1.581V5.4c0-.84 0-1.26-.163-1.581a1.5 1.5 0 0 0-.656-.656C8.861 3 8.441 3 7.6 3h-.2c-.84 0-1.26 0-1.581.163a1.5 1.5 0 0 0-.656.656zm9 0C14 4.139 14 4.559 14 5.4v13.2c0 .84 0 1.26.164 1.581a1.5 1.5 0 0 0 .655.655c.32.164.74.164 1.581.164h.2c.84 0 1.26 0 1.581-.163a1.5 1.5 0 0 0 .655-.656c.164-.32.164-.74.164-1.581V5.4c0-.84 0-1.26-.163-1.581a1.5 1.5 0 0 0-.656-.656C17.861 3 17.441 3 16.6 3h-.2c-.84 0-1.26 0-1.581.163a1.5 1.5 0 0 0-.655.656z', fill: '#FFFFFF' }) }))); };
var FullscreenOpenIcon = function (props) { return (jsxs(Icon, __assign({}, props, { viewbox: '0 0 24 24' }, { children: [jsx("path", { d: 'M4 2C2.89543 2 2 2.89543 2 4V8C2 8.55228 2.44772 9 3 9C3.55228 9 4 8.55228 4 8V4H8C8.55228 4 9 3.55228 9 3C9 2.44772 8.55228 2 8 2H4Z', fill: '#FFFFFF' }), jsx("path", { d: 'M20 2C21.1046 2 22 2.89543 22 4V8C22 8.55228 21.5523 9 21 9C20.4477 9 20 8.55228 20 8V4H16C15.4477 4 15 3.55228 15 3C15 2.44772 15.4477 2 16 2H20Z', fill: '#FFFFFF' }), jsx("path", { d: 'M20 22C21.1046 22 22 21.1046 22 20V16C22 15.4477 21.5523 15 21 15C20.4477 15 20 15.4477 20 16V20H16C15.4477 20 15 20.4477 15 21C15 21.5523 15.4477 22 16 22H20Z', fill: '#FFFFFF' }), jsx("path", { d: 'M2 20C2 21.1046 2.89543 22 4 22H8C8.55228 22 9 21.5523 9 21C9 20.4477 8.55228 20 8 20H4V16C4 15.4477 3.55228 15 3 15C2.44772 15 2 15.4477 2 16V20Z', fill: '#FFFFFF' })] }))); };
var FullscreenCloseIcon = function (props) { return (jsxs(Icon, __assign({}, props, { viewbox: '0 0 24 24' }, { children: [jsx("path", { d: 'M7 9C8.10457 9 9 8.10457 9 7V3C9 2.44772 8.55228 2 8 2C7.44772 2 7 2.44772 7 3V7H3C2.44772 7 2 7.44772 2 8C2 8.55228 2.44772 9 3 9H7Z', fill: '#FFFFFF' }), jsx("path", { d: 'M17 9C15.8954 9 15 8.10457 15 7V3C15 2.44772 15.4477 2 16 2C16.5523 2 17 2.44772 17 3V7H21C21.5523 7 22 7.44772 22 8C22 8.55228 21.5523 9 21 9H17Z', fill: '#FFFFFF' }), jsx("path", { d: 'M17 15C15.8954 15 15 15.8954 15 17V21C15 21.5523 15.4477 22 16 22C16.5523 22 17 21.5523 17 21V17H21C21.5523 17 22 16.5523 22 16C22 15.4477 21.5523 15 21 15H17Z', fill: '#FFFFFF' }), jsx("path", { d: 'M9 17C9 15.8954 8.10457 15 7 15H3C2.44772 15 2 15.4477 2 16C2 16.5523 2.44772 17 3 17H7V21C7 21.5523 7.44772 22 8 22C8.55228 22 9 21.5523 9 21V17Z', fill: '#FFFFFF' })] }))); };
var VolumeIcon = function (props) { return (jsxs(Icon, __assign({}, props, { viewbox: '0 0 48 48' }, { children: [jsx("path", { d: 'M29,4a.9.9,0,0,0-.7.3L16.7,15H8a2,2,0,0,0-2,2V31a2,2,0,0,0,2,2h8.7L28.3,43.7a.9.9,0,0,0,.7.3,1,1,0,0,0,1-1V5a1,1,0,0,0-1-1Z', fill: '#FFFFFF' }), jsx("path", { d: 'M36,42a2.1,2.1,0,0,1-1.6-.8,2,2,0,0,1,.4-2.8,18,18,0,0,0,0-28.8,2,2,0,1,1,2.4-3.2A22.4,22.4,0,0,1,46,24a22.4,22.4,0,0,1-8.8,17.6A1.7,1.7,0,0,1,36,42Z', fill: '#FFFFFF' }), jsx("path", { d: 'M34,15.5v17a.5.5,0,0,0,.9.3,14,14,0,0,0,0-17.6A.5.5,0,0,0,34,15.5Z', fill: '#FFFFFF' })] }))); };
var VolumeMuteIcon = function (props) { return (jsxs(Icon, __assign({}, props, { viewbox: '0 0 48 48' }, { children: [jsx("path", { d: 'M30,22.2V5a1,1,0,0,0-1-1,1.1,1.1,0,0,0-.7.3l-8.4,7.8Z', fill: '#FFFFFF' }), jsx("path", { d: 'M40.4,38.6l-32-32A2,2,0,0,0,5.6,9.4L11.2,15H8a2,2,0,0,0-2,2V31a2,2,0,0,0,2,2h8.7L28.3,43.7a1.1,1.1,0,0,0,.7.3,1,1,0,0,0,1-1V33.8l7.6,7.6a1.9,1.9,0,0,0,2.8,0A1.9,1.9,0,0,0,40.4,38.6Z', fill: '#FFFFFF' })] }))); };
function MidControls(_a) {
var playing = _a.playing, midControls = _a.midControls, togglePlayState = _a.togglePlayState;
if (midControls) {
return midControls(playing, togglePlayState);
}
var _b = useState(false), showIcon = _b[0], setShowIcon = _b[1];
var divRef = useRef(null);
// EVENT (click): handling animating icon in/out
useEffect(function () {
var timeoutId;
var handleOnClick = function () {
setShowIcon(true);
clearTimeout(timeoutId);
timeoutId = setTimeout(function () { return setShowIcon(false); }, 200);
};
if (divRef.current) {
divRef.current.onclick = handleOnClick;
}
}, []);
return (jsx(Wrapper$5, __assign({ onClick: togglePlayState, ref: divRef, animate: { opacity: showIcon ? 1 : 0 } }, { children: jsx(IconWrapper, { children: playing ? jsx(PauseIcon, { onClick: togglePlayState }) : jsx(PlayIcon, { onClick: togglePlayState }) }) })));
}
var Wrapper$5 = styled(motion.div)(templateObject_1$6 || (templateObject_1$6 = __makeTemplateObject(["\n height: 100%;\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n"], ["\n height: 100%;\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n"])));
var IconWrapper = styled.div(templateObject_2$5 || (templateObject_2$5 = __makeTemplateObject(["\n background-color: rgba(0, 0, 0, 0.4);\n border-radius: 50%;\n padding: 1rem;\n display: grid;\n place-items: center;\n"], ["\n background-color: rgba(0, 0, 0, 0.4);\n border-radius: 50%;\n padding: 1rem;\n display: grid;\n place-items: center;\n"])));
var templateObject_1$6, templateObject_2$5;
var secondsToTimestamp = function (seconds) {
var _minutes = Math.floor(seconds / 60);
var _seconds = Math.floor(seconds % 60);
if (_seconds < 10) {
_seconds = "0".concat(_seconds);
}
return "".concat(_minutes, ":").concat(_seconds);
};
var Input1 = styled(motion.input)(templateObject_1$5 || (templateObject_1$5 = __makeTemplateObject(["\n font-size: 1.5rem;\n width: 100%;\n color: #ef233c;\n --thumb-height: 0.7em;\n --track-height: 0.125em;\n --track-color: rgba(200, 200, 200, 0.4);\n --brightness-hover: 180%;\n --brightness-down: 80%;\n --clip-edges: 0.125em;\n position: relative;\n background: #fff0;\n overflow: hidden;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n\n &:active {\n cursor: grabbing;\n }\n\n &:disabled {\n filter: grayscale(1);\n opacity: 0.3;\n cursor: not-allowed;\n }\n\n &::-moz-range-track,\n &::-moz-range-thumb {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n transition: all ease 100ms;\n height: var(--thumb-height);\n }\n\n &::-moz-range-track,\n &::-moz-range-thumb,\n &::-moz-range-progress {\n background: #fff0;\n }\n\n &::-moz-range-thumb {\n background: currentColor;\n border: 0;\n width: var(--thumb-width, var(--thumb-height));\n border-radius: var(--thumb-width, var(--thumb-height));\n cursor: grab;\n }\n\n &:active::-moz-range-thumb {\n cursor: grabbing;\n }\n\n &::-moz-range-track {\n width: 100%;\n background: var(--track-color);\n }\n\n &::-moz-range-progress {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n background: currentColor;\n transition-delay: 30ms;\n }\n\n &::-moz-range-track,\n &::-moz-range-progress {\n height: calc(var(--track-height) + 1px);\n border-radius: var(--track-height);\n }\n\n &::-moz-range-thumb,\n &::-moz-range-progress {\n filter: brightness(100%);\n }\n\n &:hover::-moz-range-thumb,\n &:hover::-moz-range-progress {\n filter: brightness(var(--brightness-hover));\n }\n\n &:active::-moz-range-thumb,\n &:active::-moz-range-progress {\n filter: brightness(var(--brightness-down));\n }\n\n &:disabled::-moz-range-thumb {\n cursor: not-allowed;\n }\n\n &::-webkit-slider-runnable-track,\n &::-webkit-slider-thumb {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n transition: all ease 100ms;\n height: var(--thumb-height);\n }\n\n &::-webkit-slider-runnable-track,\n &::-webkit-slider-thumb {\n position: relative;\n }\n\n &::-webkit-slider-thumb {\n --thumb-radius: calc((var(--thumb-height) * 0.5) - 1px);\n --clip-top: calc((var(--thumb-height) - var(--track-height)) * 0.5 - 0.5px);\n --clip-bottom: calc(var(--thumb-height) - var(--clip-top));\n --clip-further: calc(100% + 1px);\n --box-fill: calc(-100vmax - var(--thumb-width, var(--thumb-height))) 0 0 100vmax currentColor;\n\n width: var(--thumb-width, var(--thumb-height));\n background: linear-gradient(currentColor 0 0) scroll no-repeat left center / 50%\n calc(var(--track-height) + 1px);\n background-color: currentColor;\n box-shadow: var(--box-fill);\n border-radius: var(--thumb-width, var(--thumb-height));\n\n filter: brightness(100%);\n clip-path: polygon(\n 100% -1px,\n var(--clip-edges) -1px,\n 0 var(--clip-top),\n -100vmax var(--clip-top),\n -100vmax var(--clip-bottom),\n 0 var(--clip-bottom),\n var(--clip-edges) 100%,\n var(--clip-further) var(--clip-further)\n );\n }\n\n &:hover::-webkit-slider-thumb {\n filter: brightness(var(--brightness-hover));\n cursor: grab;\n }\n\n &:active::-webkit-slider-thumb {\n filter: brightness(var(--brightness-down));\n cursor: grabbing;\n }\n\n &::-webkit-slider-runnable-track {\n background: linear-gradient(var(--track-color) 0 0) scroll no-repeat center / 100%\n calc(var(--track-height) + 1px);\n }\n\n &:disabled::-webkit-slider-thumb {\n cursor: not-allowed;\n }\n"], ["\n font-size: 1.5rem;\n width: 100%;\n color: #ef233c;\n --thumb-height: 0.7em;\n --track-height: 0.125em;\n --track-color: rgba(200, 200, 200, 0.4);\n --brightness-hover: 180%;\n --brightness-down: 80%;\n --clip-edges: 0.125em;\n position: relative;\n background: #fff0;\n overflow: hidden;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n\n &:active {\n cursor: grabbing;\n }\n\n &:disabled {\n filter: grayscale(1);\n opacity: 0.3;\n cursor: not-allowed;\n }\n\n &::-moz-range-track,\n &::-moz-range-thumb {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n transition: all ease 100ms;\n height: var(--thumb-height);\n }\n\n &::-moz-range-track,\n &::-moz-range-thumb,\n &::-moz-range-progress {\n background: #fff0;\n }\n\n &::-moz-range-thumb {\n background: currentColor;\n border: 0;\n width: var(--thumb-width, var(--thumb-height));\n border-radius: var(--thumb-width, var(--thumb-height));\n cursor: grab;\n }\n\n &:active::-moz-range-thumb {\n cursor: grabbing;\n }\n\n &::-moz-range-track {\n width: 100%;\n background: var(--track-color);\n }\n\n &::-moz-range-progress {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n background: currentColor;\n transition-delay: 30ms;\n }\n\n &::-moz-range-track,\n &::-moz-range-progress {\n height: calc(var(--track-height) + 1px);\n border-radius: var(--track-height);\n }\n\n &::-moz-range-thumb,\n &::-moz-range-progress {\n filter: brightness(100%);\n }\n\n &:hover::-moz-range-thumb,\n &:hover::-moz-range-progress {\n filter: brightness(var(--brightness-hover));\n }\n\n &:active::-moz-range-thumb,\n &:active::-moz-range-progress {\n filter: brightness(var(--brightness-down));\n }\n\n &:disabled::-moz-range-thumb {\n cursor: not-allowed;\n }\n\n &::-webkit-slider-runnable-track,\n &::-webkit-slider-thumb {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n transition: all ease 100ms;\n height: var(--thumb-height);\n }\n\n &::-webkit-slider-runnable-track,\n &::-webkit-slider-thumb {\n position: relative;\n }\n\n &::-webkit-slider-thumb {\n --thumb-radius: calc((var(--thumb-height) * 0.5) - 1px);\n --clip-top: calc((var(--thumb-height) - var(--track-height)) * 0.5 - 0.5px);\n --clip-bottom: calc(var(--thumb-height) - var(--clip-top));\n --clip-further: calc(100% + 1px);\n --box-fill: calc(-100vmax - var(--thumb-width, var(--thumb-height))) 0 0 100vmax currentColor;\n\n width: var(--thumb-width, var(--thumb-height));\n background: linear-gradient(currentColor 0 0) scroll no-repeat left center / 50%\n calc(var(--track-height) + 1px);\n background-color: currentColor;\n box-shadow: var(--box-fill);\n border-radius: var(--thumb-width, var(--thumb-height));\n\n filter: brightness(100%);\n clip-path: polygon(\n 100% -1px,\n var(--clip-edges) -1px,\n 0 var(--clip-top),\n -100vmax var(--clip-top),\n -100vmax var(--clip-bottom),\n 0 var(--clip-bottom),\n var(--clip-edges) 100%,\n var(--clip-further) var(--clip-further)\n );\n }\n\n &:hover::-webkit-slider-thumb {\n filter: brightness(var(--brightness-hover));\n cursor: grab;\n }\n\n &:active::-webkit-slider-thumb {\n filter: brightness(var(--brightness-down));\n cursor: grabbing;\n }\n\n &::-webkit-slider-runnable-track {\n background: linear-gradient(var(--track-color) 0 0) scroll no-repeat center / 100%\n calc(var(--track-height) + 1px);\n }\n\n &:disabled::-webkit-slider-thumb {\n cursor: not-allowed;\n }\n"])));
styled.input(templateObject_2$4 || (templateObject_2$4 = __makeTemplateObject(["\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n margin: 10px 0;\n width: 100%;\n background: none;\n\n &:focus {\n outline: none;\n }\n\n &::-webkit-slider-runnable-track {\n width: 100%;\n height: 6px;\n cursor: pointer;\n box-shadow:\n 0px 0px 0px #000000,\n 0px 0px 0px #0d0d0d;\n background: #f07167;\n border-radius: 25px;\n border: 0px solid #111111;\n }\n\n &::-webkit-slider-thumb {\n box-shadow:\n 0px 0px 0px #000000,\n 0px 0px 0px #0d0d0d;\n border: 0px solid #111111;\n height: 0px;\n width: 0px;\n border-radius: 7px;\n background: #111111;\n cursor: pointer;\n -webkit-appearance: none;\n margin-top: -3.6px;\n }\n\n &:focus::-webkit-slider-runnable-track {\n background: #f07167;\n }\n\n &::-moz-range-track {\n width: 100%;\n height: 6px;\n cursor: pointer;\n animate: 0.2s;\n box-shadow:\n 0px 0px 0px #111111,\n 0px 0px 0px #0d0d0d;\n background: rgba(0, 0, 0, 0.2);\n border: 0px solid #111111;\n }\n\n &::-moz-range-thumb {\n background: transparent;\n border: none;\n cursor: pointer;\n }\n\n &::-moz-range-progress {\n background: #f07167;\n height: 6px;\n }\n\n &::-ms-track {\n width: 100%;\n height: 6px;\n cursor: pointer;\n animate: 0.2s;\n background: transparent;\n border-color: transparent;\n border-width: 39px 0;\n color: transparent;\n }\n\n &::-ms-fill-lower {\n background: #f07167;\n border: 0px solid #111111;\n border-radius: 50px;\n box-shadow:\n 0px 0px 0px #111111,\n 0px 0px 0px #0d0d0d;\n }\n\n &::-ms-fill-upper {\n background: #f07167;\n border: 0px solid #111111;\n border-radius: 50px;\n box-shadow:\n 0px 0px 0px #111111,\n 0px 0px 0px #0d0d0d;\n }\n\n &::-ms-thumb {\n box-shadow:\n 0px 0px 0px #111111,\n 0px 0px 0px #0d0d0d;\n border: 0px solid #111111;\n height: 15px;\n width: 25px;\n border-radius: 7px;\n background: #111111;\n cursor: pointer;\n }\n\n &:focus::-ms-fill-lower {\n background: #f07167;\n }\n\n &:focus::-ms-fill-upper {\n background: #f07167;\n }\n"], ["\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n margin: 10px 0;\n width: 100%;\n background: none;\n\n &:focus {\n outline: none;\n }\n\n &::-webkit-slider-runnable-track {\n width: 100%;\n height: 6px;\n cursor: pointer;\n box-shadow:\n 0px 0px 0px #000000,\n 0px 0px 0px #0d0d0d;\n background: #f07167;\n border-radius: 25px;\n border: 0px solid #111111;\n }\n\n &::-webkit-slider-thumb {\n box-shadow:\n 0px 0px 0px #000000,\n 0px 0px 0px #0d0d0d;\n border: 0px solid #111111;\n height: 0px;\n width: 0px;\n border-radius: 7px;\n background: #111111;\n cursor: pointer;\n -webkit-appearance: none;\n margin-top: -3.6px;\n }\n\n &:focus::-webkit-slider-runnable-track {\n background: #f07167;\n }\n\n &::-moz-range-track {\n width: 100%;\n height: 6px;\n cursor: pointer;\n animate: 0.2s;\n box-shadow:\n 0px 0px 0px #111111,\n 0px 0px 0px #0d0d0d;\n background: rgba(0, 0, 0, 0.2);\n border: 0px solid #111111;\n }\n\n &::-moz-range-thumb {\n background: transparent;\n border: none;\n cursor: pointer;\n }\n\n &::-moz-range-progress {\n background: #f07167;\n height: 6px;\n }\n\n &::-ms-track {\n width: 100%;\n height: 6px;\n cursor: pointer;\n animate: 0.2s;\n background: transparent;\n border-color: transparent;\n border-width: 39px 0;\n color: transparent;\n }\n\n &::-ms-fill-lower {\n background: #f07167;\n border: 0px solid #111111;\n border-radius: 50px;\n box-shadow:\n 0px 0px 0px #111111,\n 0px 0px 0px #0d0d0d;\n }\n\n &::-ms-fill-upper {\n background: #f07167;\n border: 0px solid #111111;\n border-radius: 50px;\n box-shadow:\n 0px 0px 0px #111111,\n 0px 0px 0px #0d0d0d;\n }\n\n &::-ms-thumb {\n box-shadow:\n 0px 0px 0px #111111,\n 0px 0px 0px #0d0d0d;\n border: 0px solid #111111;\n height: 15px;\n width: 25px;\n border-radius: 7px;\n background: #111111;\n cursor: pointer;\n }\n\n &:focus::-ms-fill-lower {\n background: #f07167;\n }\n\n &:focus::-ms-fill-upper {\n background: #f07167;\n }\n"])));
var templateObject_1$5, templateObject_2$4;
function ProgressBar(_a) {
var duration = _a.duration, progress = _a.progress, seekTo = _a.seekTo;
var inputRef = useRef(null);
var state = usePlayerContext(PContext).state;
var _b = useState(), labelOffset = _b[0], setLabelOffset = _b[1];
var _c = useState(0), labelTimestamp = _c[0], setLabelTimestamp = _c[1];
useLayoutEffect(function () {
if (inputRef.current) {
if (state.accentColor) {
inputRef.current.style.color = state.accentColor;
}
}
}, [inputRef, state.accentColor]);
var showTooltip = function (e) {
if (inputRef.current) {
var percents = e.clientX / (inputRef.current.offsetWidth + inputRef.current.offsetLeft);
var max = parseInt(inputRef.current.max);
setLabelTimestamp(Math.floor(percents * max));
setLabelOffset(e.clientX - inputRef.current.offsetLeft - 24);
}
};
var hideTooltip = function () { return setLabelOffset(undefined); };
return (jsxs(Wrapper$4, { children: [jsx(Input1, { animate: { opacity: state.volumeSliderOpen ? 0 : 1 }, transition: { duration: 0.15 }, ref: inputRef, type: 'range', min: '0', max: Math.ceil(duration).toString(), value: progress, onChange: seekTo, onMouseMove: showTooltip, onMouseOut: hideTooltip }), jsx(TooptipWrapper, __assign({ "$show": !!labelOffset }, { children: jsx(Tooltip, __assign({ "$offset": labelOffset }, { children: jsx(TooltipText, { children: secondsToTimestamp(labelTimestamp) }) })) }))] }));
}
var Wrapper$4 = styled.div(templateObject_1$4 || (templateObject_1$4 = __makeTemplateObject(["\n width: 100%;\n margin: 0 auto;\n display: flex;\n align-items: center;\n\n &::before,\n &::after {\n display: block;\n position: absolute;\n z-index: 99;\n color: #fff;\n width: 100%;\n text-align: center;\n font-size: 1.5rem;\n line-height: 1;\n padding: 0.75rem 0;\n pointer-events: none;\n }\n"], ["\n width: 100%;\n margin: 0 auto;\n display: flex;\n align-items: center;\n\n &::before,\n &::after {\n display: block;\n position: absolute;\n z-index: 99;\n color: #fff;\n width: 100%;\n text-align: center;\n font-size: 1.5rem;\n line-height: 1;\n padding: 0.75rem 0;\n pointer-events: none;\n }\n"])));
var TooptipWrapper = styled.div(templateObject_2$3 || (templateObject_2$3 = __makeTemplateObject(["\n position: absolute;\n pointer-events: none;\n display: ", ";\n"], ["\n position: absolute;\n pointer-events: none;\n display: ", ";\n"])), function (props) { return (props.$show ? 'block' : 'none'); });
var Tooltip = styled.div(templateObject_3$2 || (templateObject_3$2 = __makeTemplateObject(["\n background: #fff;\n border-radius: 5px;\n padding: 5px 10px;\n text-align: left;\n position: relative;\n font-size: 0.8rem;\n max-width: 140px;\n bottom: 26px;\n right: ", "px;\n"], ["\n background: #fff;\n border-radius: 5px;\n padding: 5px 10px;\n text-align: left;\n position: relative;\n font-size: 0.8rem;\n max-width: 140px;\n bottom: 26px;\n right: ", "px;\n"])), function (props) { return (props.$offset ? -props.$offset : 0); });
var TooltipText = styled.span(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n font-style: italic;\n font-family: sans-serif;\n"], ["\n font-style: italic;\n font-family: sans-serif;\n"])));
var templateObject_1$4, templateObject_2$3, templateObject_3$2, templateObject_4;
function VolumeSlider(_a) {
var changeVolume = _a.changeVolume, toggleMute = _a.toggleMute;
var inputRef = useRef(null);
var _b = useState(false), showVolumeSlider = _b[0], setShowVolumeSlider = _b[1];
var _c = usePlayerContext(PContext), state = _c.state, setState = _c.setState;
useLayoutEffect(function () {
if (inputRef.current) {
if (state.accentColor) {
inputRef.current.style.color = state.accentColor;
}
}
}, [inputRef]);
var onMouseOverSlider = function () {
setShowVolumeSlider(true);
setState(function (prev) { return (__assign(__assign({}, prev), { volumeSliderOpen: true })); });
};
var onMouseLeaveSlider = function () {
setShowVolumeSlider(false);
setState(function (prev) { return (__assign(__assign({}, prev), { volumeSliderOpen: false })); });
};
var setVolume = function (e) {
changeVolume(Number(e.currentTarget.value));
};
var renderIcon = function () {
if (state.currentVolume > 0) {
return jsx(VolumeIcon, { onClick: toggleMute, width: 26, height: 26 });
}
else {
return jsx(VolumeMuteIcon, { onClick: toggleMute, width: 26, height: 26 });
}
};
return (jsxs(Wrapper$3, __assign({ onMouseOver: onMouseOverSlider, onMouseOut: onMouseLeaveSlider }, { children: [jsx(SliderWrapper, { children: jsx(Input, { ref: inputRef, type: 'range', onChange: setVolume, value: state.currentVolume, min: '0', max: '1', step: '0.01', style: { display: showVolumeSlider ? 'block' : 'none' } }) }), renderIcon()] })));
}
var Wrapper$3 = styled.div(templateObject_1$3 || (templateObject_1$3 = __makeTemplateObject(["\n margin-left: 1rem;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n position: relative;\n cursor: pointer;\n"], ["\n margin-left: 1rem;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n position: relative;\n cursor: pointer;\n"])));
var SliderWrapper = styled.div(templateObject_2$2 || (templateObject_2$2 = __makeTemplateObject(["\n position: absolute;\n bottom: 1rem;\n"], ["\n position: absolute;\n bottom: 1rem;\n"])));
var Input = styled(Input1)(templateObject_3$1 || (templateObject_3$1 = __makeTemplateObject(["\n transform: rotate(-90deg);\n width: 4rem;\n margin-bottom: 1.5rem;\n padding-left: 1rem;\n cursor: pointer;\n"], ["\n transform: rotate(-90deg);\n width: 4rem;\n margin-bottom: 1.5rem;\n padding-left: 1rem;\n cursor: pointer;\n"])));
var templateObject_1$3, templateObject_2$2, templateObject_3$1;
function FullscreenIcon(_a) {
var isFullscreen = _a.isFullscreen, toggleFullscreen = _a.toggleFullscreen;
var renderIcon = function () {
if (isFullscreen) {
return jsx(FullscreenCloseIcon, { height: 26, width: 26 });
}
else {
return jsx(FullscreenOpenIcon, { height: 26, width: 26 });
}
};
return jsx(Wrapper$2, __assign({ onClick: toggleFullscreen }, { children: renderIcon() }));
}
var Wrapper$2 = styled.div(templateObject_1$2 || (templateObject_1$2 = __makeTemplateObject(["\n display: flex;\n align-items: center;\n justify-content: center;\n margin-left: 0.5rem;\n cursor: pointer;\n"], ["\n display: flex;\n align-items: center;\n justify-content: center;\n margin-left: 0.5rem;\n cursor: pointer;\n"])));
var templateObject_1$2;
function PlayButton(_a) {
var playing = _a.playing, togglePlay = _a.togglePlay;
if (playing) {
return jsx(PauseIcon, { onClick: togglePlay, height: 24, width: 24 });
}
else {
return jsx(PlayIcon, { onClick: togglePlay, height: 24, width: 24 });
}
}
function BottomControls(_a) {
var progress = _a.progress, bottomControls = _a.bottomControls, seekTo = _a.seekTo, changeVolume = _a.changeVolume, toggleFullscreen = _a.toggleFullscreen, toggleMute = _a.toggleMute, togglePlay = _a.togglePlay;
var state = usePlayerContext(PContext).state;
if (bottomControls) {
return bottomControls(progress, state.duration, seekTo, changeVolume, toggleFullscreen, toggleMute, togglePlay);
}
return (jsxs(Wrapper$1, { children: [jsx(ProgressBar, { duration: state.duration, progress: progress, seekTo: seekTo }), jsxs(BottomWrapper, { children: [jsx(PlayButtonWrapper, { children: jsx(PlayButton, { playing: state.playing, togglePlay: togglePlay }) }), jsx(VolumeSlider, { changeVolume: changeVolume, toggleMute: toggleMute }), jsx(FullscreenIcon, { toggleFullscreen: toggleFullscreen, isFullscreen: state.isFullscreen })] })] }));
}
var Wrapper$1 = styled.div(templateObject_1$1 || (templateObject_1$1 = __makeTemplateObject(["\n display: grid;\n grid-template-rows: 50% 50%;\n margin-top: auto;\n width: 95%;\n margin-right: 10px;\n margin-left: 10px;\n"], ["\n display: grid;\n grid-template-rows: 50% 50%;\n margin-top: auto;\n width: 95%;\n margin-right: 10px;\n margin-left: 10px;\n"])));
var BottomWrapper = styled.div(templateObject_2$1 || (templateObject_2$1 = __makeTemplateObject(["\n display: flex;\n flex-direction: row;\n padding-bottom: 15px;\n margin-left: auto;\n width: 100%;\n"], ["\n display: flex;\n flex-direction: row;\n padding-bottom: 15px;\n margin-left: auto;\n width: 100%;\n"])));
var PlayButtonWrapper = styled.div(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n margin-right: auto;\n padding-left: 5px;\n display: grid;\n place-items: center;\n"], ["\n margin-right: auto;\n padding-left: 5px;\n display: grid;\n place-items: center;\n"])));
var templateObject_1$1, templateObject_2$1, templateObject_3;
function TopControls(_a) {
var topControls = _a.topControls;
if (topControls) {
return topControls();
}
else
return jsx("div", {});
}
function Player(_a) {
var _b;
var autoplay = _a.autoplay, height = _a.height, src = _a.src, _c = _a.videoType, videoType = _c === void 0 ? 'mp4' : _c, width = _a.width, bottomControls = _a.bottomControls, midControls = _a.midControls, topControls = _a.topControls;
var playerRef = useRef(null);
var playerWrapperRef = useRef(null);
var _d = useState(((_b = playerRef.current) === null || _b === void 0 ? void 0 : _b.currentTime) || 0), currentTime = _d[0], setCurrentTime = _d[1];
var _e = usePlayerContext(PContext), state = _e.state, setState = _e.setState;
// Update when new src
useEffect(function () {
setCurrentTime(0);
}, [src]);
// Setting state in here as pressing `esc` needs to trigger state updates too
useEffect(function () {
screenfull.onchange(function () {
setState(function (prev) { return (__assign(__assign({}, prev), { isFullscreen: !prev.isFullscreen })); });
});
}, [screenfull]);
useEffect(function () {
var interval = setInterval(function () {
var _a;
if (state.playing) {
setCurrentTime(Math.floor(((_a = playerRef.current) === null || _a === void 0 ? void 0 : _a.currentTime) || 0));
}
}, 1000);
return function () { return clearInterval(interval); };
}, [state.playing]);
useLayoutEffect(function () {
if (playerRef.current) {
var current_1 = playerRef.current;
setState(function (prev) { return (__assign(__assign({}, prev), { duration: current_1.duration })); });
}
}, []);
var togglePlaying = function () {
var _a, _b;
if (state.playing) {
(_a = playerRef.current) === null || _a === void 0 ? void 0 : _a.pause();
setState(function (prev) { return (__assign(__assign({}, prev), { playing: false })); });
}
else {
(_b = playerRef.current) === null || _b === void 0 ? void 0 : _b.play();
setState(function (prev) { return (__assign(__assign({}, prev), { playing: true })); });
}
};
var seek = function (e) {
if (playerRef.current) {
var value = Number(e.currentTarget.value);
playerRef.current.currentTime = value;
setCurrentTime(value);
}
};
var changeVolume = function (newVolume) {
if (playerRef.current) {
playerRef.current.volume = newVolume;
setState(function (prev) { return (__assign(__assign({}, prev), { currentVolume: newVolume })); });
if (newVolume > 0) {
setState(function (prev) { return (__assign(__assign({}, prev), { previousVolume: newVolume })); });
}
}
};
var toggleMute = function () {
if (playerRef.current) {
var newVolume_1;
if (state.currentVolume > 0) {
newVolume_1 = 0;
}
else {
newVolume_1 = state.previousVolume;
}
setState(function (prev) { return (__assign(__assign({}, prev), { currentVolume: newVolume_1 })); });
}
};
var toggleFullscreen = function () {
if (screenfull.isEnabled) {
if (screenfull.isFullscreen) {
screenfull.exit();
}
else {
screenfull.request();
}
}
};
var onLoad = function () {
if (playerRef.current) {
var boundingRect_1 = playerRef.current.getBoundingClientRect();
var duration_1 = playerRef.current.duration;
setState(function (prev) { return (__assign(__assign({}, prev), { viewportHeight: boundingRect_1.height, viewportWidth: boundingRect_1.width, duration: duration_1 })); });
}
};
return (jsxs(Wrapper, __assign({ ref: playerWrapperRef, id: 'player', "$isFullscreen": state.isFullscreen, "$width": width, "$height": height }, { children: [jsxs(PlayerControls, __assign({ playerRef: playerRef, wrapperRef: playerWrapperRef }, { children: [jsx(TopControls, { topControls: topControls }), jsx(MidControls, { midControls: midControls, playing: state.playing, togglePlayState: togglePlaying }), jsx(BottomControls, { bottomControls: bottomControls, progress: currentTime, seekTo: seek, changeVolume: changeVolume, toggleFullscreen: toggleFullscreen, toggleMute: toggleMute, togglePlay: togglePlaying })] })), jsx(Video, __assign({ ref: playerRef, onLoadedMetadata: onLoad, autoPlay: autoplay }, { children: jsx("source", { src: src, type: "video/".concat(videoType) }) }))] })));
}
var Wrapper = styled.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n width: ", ";\n height: ", ";\n display: flex;\n justify-content: center;\n align-items: center;\n max-height: 100vh;\n background-color: ", ";\n"], ["\n width: ", ";\n height: ", ";\n display: flex;\n justify-content: center;\n align-items: center;\n max-height: 100vh;\n background-color: ", ";\n"])), function (props) { return (props.$isFullscreen ? '100%' : props.$width ? "".concat(props.$width, "px") : '100%'); }, function (props) { return (props.$isFullscreen ? '100vh' : props.$height ? "".concat(props.$height, "px") : ''); }, function (props) { return (props.$isFullscreen ? 'black' : ''); });
var Video = styled.video(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n max-height: 100vh;\n width: 100%;\n"], ["\n max-height: 100vh;\n width: 100%;\n"])));
var templateObject_1, templateObject_2;
var PlayerWrapper = function (props) { return (jsx(PlayerContextProvider, __assign({ state: {
accentColor: props.accentColor,
currentVolume: 1,
duration: 0,
isFullscreen: false,
previousVolume: 1,
playing: false,
volumeSliderOpen: false,
viewportHeight: 0,
viewportWidth: 0,
} }, { children: jsx(Player, __assign({}, props)) }))); };
export { PlayerWrapper as default };