react-smart-player
Version:
A lightweight and customizable video player by Naresh Dev, built for seamless streaming with advanced controls, adaptive playback, and modern UI. Perfect for web and React applications.
406 lines (381 loc) • 84.6 kB
JavaScript
import * as React from 'react';
import React__default, { memo, useCallback, useEffect, useRef, useState } from 'react';
import { create } from 'zustand';
import { FaCheck, FaGooglePlay } from 'react-icons/fa';
import { IoVolumeMuteOutline, IoVolumeHighOutline } from 'react-icons/io5';
import { Settings, Loader } from 'lucide-react';
import { IoMdClose } from 'react-icons/io';
import Hls from 'hls.js';
function styleInject(css, ref) {
if ( ref === void 0 ) ref = {};
var insertAt = ref.insertAt;
if (!css || typeof document === 'undefined') { return; }
var head = document.head || document.getElementsByTagName('head')[0];
var style = document.createElement('style');
style.type = 'text/css';
if (insertAt === 'top') {
if (head.firstChild) {
head.insertBefore(style, head.firstChild);
} else {
head.appendChild(style);
}
} else {
head.appendChild(style);
}
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
}
var css_248z$2 = "/*! tailwindcss v4.1.13 | MIT License | https://tailwindcss.com */\n@layer properties;\n@layer theme, base, components, utilities;\n@layer theme {\n :root, :host {\n --font-sans: ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\",\n \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\",\n \"Courier New\", monospace;\n --color-green-100: oklch(96.2% 0.044 156.743);\n --color-green-500: oklch(72.3% 0.219 149.579);\n --color-gray-50: oklch(98.5% 0.002 247.839);\n --color-gray-200: oklch(92.8% 0.006 264.531);\n --color-gray-300: oklch(87.2% 0.01 258.338);\n --color-gray-400: oklch(70.7% 0.022 261.325);\n --color-gray-500: oklch(55.1% 0.027 264.364);\n --color-gray-700: oklch(37.3% 0.034 259.733);\n --color-gray-900: oklch(21% 0.034 264.665);\n --color-black: #000;\n --color-white: #fff;\n --spacing: 0.25rem;\n --text-sm: 0.875rem;\n --text-sm--line-height: calc(1.25 / 0.875);\n --text-base: 1rem;\n --text-base--line-height: calc(1.5 / 1);\n --text-lg: 1.125rem;\n --text-lg--line-height: calc(1.75 / 1.125);\n --text-xl: 1.25rem;\n --text-xl--line-height: calc(1.75 / 1.25);\n --text-2xl: 1.5rem;\n --text-2xl--line-height: calc(2 / 1.5);\n --text-3xl: 1.875rem;\n --text-3xl--line-height: calc(2.25 / 1.875);\n --text-4xl: 2.25rem;\n --text-4xl--line-height: calc(2.5 / 2.25);\n --font-weight-medium: 500;\n --font-weight-semibold: 600;\n --font-weight-bold: 700;\n --radius-md: 0.375rem;\n --radius-lg: 0.5rem;\n --radius-xl: 0.75rem;\n --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);\n --animate-spin: spin 1s linear infinite;\n --blur-sm: 8px;\n --blur-md: 12px;\n --default-transition-duration: 150ms;\n --default-transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);\n --default-font-family: var(--font-sans);\n --default-mono-font-family: var(--font-mono);\n }\n}\n@layer base {\n *, ::after, ::before, ::backdrop, ::file-selector-button {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n border: 0 solid;\n }\n html, :host {\n line-height: 1.5;\n -webkit-text-size-adjust: 100%;\n tab-size: 4;\n font-family: var(--default-font-family, ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\");\n font-feature-settings: var(--default-font-feature-settings, normal);\n font-variation-settings: var(--default-font-variation-settings, normal);\n -webkit-tap-highlight-color: transparent;\n }\n hr {\n height: 0;\n color: inherit;\n border-top-width: 1px;\n }\n abbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n }\n h1, h2, h3, h4, h5, h6 {\n font-size: inherit;\n font-weight: inherit;\n }\n a {\n color: inherit;\n -webkit-text-decoration: inherit;\n text-decoration: inherit;\n }\n b, strong {\n font-weight: bolder;\n }\n code, kbd, samp, pre {\n font-family: var(--default-mono-font-family, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace);\n font-feature-settings: var(--default-mono-font-feature-settings, normal);\n font-variation-settings: var(--default-mono-font-variation-settings, normal);\n font-size: 1em;\n }\n small {\n font-size: 80%;\n }\n sub, sup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n }\n sub {\n bottom: -0.25em;\n }\n sup {\n top: -0.5em;\n }\n table {\n text-indent: 0;\n border-color: inherit;\n border-collapse: collapse;\n }\n :-moz-focusring {\n outline: auto;\n }\n progress {\n vertical-align: baseline;\n }\n summary {\n display: list-item;\n }\n ol, ul, menu {\n list-style: none;\n }\n img, svg, video, canvas, audio, iframe, embed, object {\n display: block;\n vertical-align: middle;\n }\n img, video {\n max-width: 100%;\n height: auto;\n }\n button, input, select, optgroup, textarea, ::file-selector-button {\n font: inherit;\n font-feature-settings: inherit;\n font-variation-settings: inherit;\n letter-spacing: inherit;\n color: inherit;\n border-radius: 0;\n background-color: transparent;\n opacity: 1;\n }\n :where(select:is([multiple], [size])) optgroup {\n font-weight: bolder;\n }\n :where(select:is([multiple], [size])) optgroup option {\n padding-inline-start: 20px;\n }\n ::file-selector-button {\n margin-inline-end: 4px;\n }\n ::placeholder {\n opacity: 1;\n }\n @supports (not (-webkit-appearance: -apple-pay-button)) or (contain-intrinsic-size: 1px) {\n ::placeholder {\n color: currentcolor;\n @supports (color: color-mix(in lab, red, red)) {\n color: color-mix(in oklab, currentcolor 50%, transparent);\n }\n }\n }\n textarea {\n resize: vertical;\n }\n ::-webkit-search-decoration {\n -webkit-appearance: none;\n }\n ::-webkit-date-and-time-value {\n min-height: 1lh;\n text-align: inherit;\n }\n ::-webkit-datetime-edit {\n display: inline-flex;\n }\n ::-webkit-datetime-edit-fields-wrapper {\n padding: 0;\n }\n ::-webkit-datetime-edit, ::-webkit-datetime-edit-year-field, ::-webkit-datetime-edit-month-field, ::-webkit-datetime-edit-day-field, ::-webkit-datetime-edit-hour-field, ::-webkit-datetime-edit-minute-field, ::-webkit-datetime-edit-second-field, ::-webkit-datetime-edit-millisecond-field, ::-webkit-datetime-edit-meridiem-field {\n padding-block: 0;\n }\n ::-webkit-calendar-picker-indicator {\n line-height: 1;\n }\n :-moz-ui-invalid {\n box-shadow: none;\n }\n button, input:where([type=\"button\"], [type=\"reset\"], [type=\"submit\"]), ::file-selector-button {\n appearance: button;\n }\n ::-webkit-inner-spin-button, ::-webkit-outer-spin-button {\n height: auto;\n }\n [hidden]:where(:not([hidden=\"until-found\"])) {\n display: none !important;\n }\n}\n@layer utilities {\n .pointer-events-none {\n pointer-events: none;\n }\n .absolute {\n position: absolute;\n }\n .relative {\n position: relative;\n }\n .inset-0 {\n inset: calc(var(--spacing) * 0);\n }\n .-top-2 {\n top: calc(var(--spacing) * -2);\n }\n .top-0 {\n top: calc(var(--spacing) * 0);\n }\n .top-1\\/2 {\n top: calc(1/2 * 100%);\n }\n .top-full {\n top: 100%;\n }\n .right-32 {\n right: calc(var(--spacing) * 32);\n }\n .right-full {\n right: 100%;\n }\n .bottom-36 {\n bottom: calc(var(--spacing) * 36);\n }\n .bottom-full {\n bottom: 100%;\n }\n .left-0 {\n left: calc(var(--spacing) * 0);\n }\n .left-1\\/2 {\n left: calc(1/2 * 100%);\n }\n .left-4 {\n left: calc(var(--spacing) * 4);\n }\n .left-32 {\n left: calc(var(--spacing) * 32);\n }\n .left-full {\n left: 100%;\n }\n .z-50 {\n z-index: 50;\n }\n .z-\\[-1\\] {\n z-index: -1;\n }\n .mx-2 {\n margin-inline: calc(var(--spacing) * 2);\n }\n .mx-auto {\n margin-inline: auto;\n }\n .mt-2 {\n margin-top: calc(var(--spacing) * 2);\n }\n .mr-2 {\n margin-right: calc(var(--spacing) * 2);\n }\n .mb-1 {\n margin-bottom: calc(var(--spacing) * 1);\n }\n .mb-2 {\n margin-bottom: calc(var(--spacing) * 2);\n }\n .ml-2 {\n margin-left: calc(var(--spacing) * 2);\n }\n .flex {\n display: flex;\n }\n .inline {\n display: inline;\n }\n .inline-block {\n display: inline-block;\n }\n .h-3 {\n height: calc(var(--spacing) * 3);\n }\n .h-5 {\n height: calc(var(--spacing) * 5);\n }\n .h-10 {\n height: calc(var(--spacing) * 10);\n }\n .h-24 {\n height: calc(var(--spacing) * 24);\n }\n .h-full {\n height: 100%;\n }\n .w-3 {\n width: calc(var(--spacing) * 3);\n }\n .w-5 {\n width: calc(var(--spacing) * 5);\n }\n .w-24 {\n width: calc(var(--spacing) * 24);\n }\n .w-56 {\n width: calc(var(--spacing) * 56);\n }\n .w-\\[2px\\] {\n width: 2px;\n }\n .w-\\[10vw\\] {\n width: 10vw;\n }\n .w-\\[15vw\\] {\n width: 15vw;\n }\n .w-fit {\n width: fit-content;\n }\n .w-full {\n width: 100%;\n }\n .-translate-x-1\\/2 {\n --tw-translate-x: calc(calc(1/2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n .-translate-y-1\\/2 {\n --tw-translate-y: calc(calc(1/2 * 100%) * -1);\n translate: var(--tw-translate-x) var(--tw-translate-y);\n }\n .rotate-45 {\n rotate: 45deg;\n }\n .transform {\n transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);\n }\n .animate-spin {\n animation: var(--animate-spin);\n }\n .cursor-not-allowed {\n cursor: not-allowed;\n }\n .cursor-pointer {\n cursor: pointer;\n }\n .flex-col {\n flex-direction: column;\n }\n .items-center {\n align-items: center;\n }\n .justify-between {\n justify-content: space-between;\n }\n .justify-center {\n justify-content: center;\n }\n .gap-1 {\n gap: calc(var(--spacing) * 1);\n }\n .gap-2 {\n gap: calc(var(--spacing) * 2);\n }\n .gap-4 {\n gap: calc(var(--spacing) * 4);\n }\n .gap-7 {\n gap: calc(var(--spacing) * 7);\n }\n .rounded-lg {\n border-radius: var(--radius-lg);\n }\n .rounded-md {\n border-radius: var(--radius-md);\n }\n .rounded-xl {\n border-radius: var(--radius-xl);\n }\n .border {\n border-style: var(--tw-border-style);\n border-width: 1px;\n }\n .border-t {\n border-top-style: var(--tw-border-style);\n border-top-width: 1px;\n }\n .border-l {\n border-left-style: var(--tw-border-style);\n border-left-width: 1px;\n }\n .border-gray-200 {\n border-color: var(--color-gray-200);\n }\n .bg-\\[rgba\\(0\\,0\\,0\\,0\\.5\\)\\] {\n background-color: rgba(0,0,0,0.5);\n }\n .bg-gray-500 {\n background-color: var(--color-gray-500);\n }\n .bg-gray-900 {\n background-color: var(--color-gray-900);\n }\n .bg-green-100 {\n background-color: var(--color-green-100);\n }\n .bg-white {\n background-color: var(--color-white);\n }\n .bg-white\\/80 {\n background-color: color-mix(in srgb, #fff 80%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 80%, transparent);\n }\n }\n .bg-white\\/90 {\n background-color: color-mix(in srgb, #fff 90%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 90%, transparent);\n }\n }\n .bg-gradient-to-b {\n --tw-gradient-position: to bottom in oklab;\n background-image: linear-gradient(var(--tw-gradient-stops));\n }\n .from-black {\n --tw-gradient-from: var(--color-black);\n --tw-gradient-stops: var(--tw-gradient-via-stops, var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));\n }\n .p-2 {\n padding: calc(var(--spacing) * 2);\n }\n .p-4 {\n padding: calc(var(--spacing) * 4);\n }\n .p-10 {\n padding: calc(var(--spacing) * 10);\n }\n .px-3 {\n padding-inline: calc(var(--spacing) * 3);\n }\n .px-6 {\n padding-inline: calc(var(--spacing) * 6);\n }\n .px-10 {\n padding-inline: calc(var(--spacing) * 10);\n }\n .py-1 {\n padding-block: calc(var(--spacing) * 1);\n }\n .py-2 {\n padding-block: calc(var(--spacing) * 2);\n }\n .pt-6 {\n padding-top: calc(var(--spacing) * 6);\n }\n .pb-10 {\n padding-bottom: calc(var(--spacing) * 10);\n }\n .pb-16 {\n padding-bottom: calc(var(--spacing) * 16);\n }\n .text-base {\n font-size: var(--text-base);\n line-height: var(--tw-leading, var(--text-base--line-height));\n }\n .text-lg {\n font-size: var(--text-lg);\n line-height: var(--tw-leading, var(--text-lg--line-height));\n }\n .text-sm {\n font-size: var(--text-sm);\n line-height: var(--tw-leading, var(--text-sm--line-height));\n }\n .text-xl {\n font-size: var(--text-xl);\n line-height: var(--tw-leading, var(--text-xl--line-height));\n }\n .font-bold {\n --tw-font-weight: var(--font-weight-bold);\n font-weight: var(--font-weight-bold);\n }\n .font-medium {\n --tw-font-weight: var(--font-weight-medium);\n font-weight: var(--font-weight-medium);\n }\n .font-semibold {\n --tw-font-weight: var(--font-weight-semibold);\n font-weight: var(--font-weight-semibold);\n }\n .text-black {\n color: var(--color-black);\n }\n .text-gray-200 {\n color: var(--color-gray-200);\n }\n .text-gray-400 {\n color: var(--color-gray-400);\n }\n .text-gray-500 {\n color: var(--color-gray-500);\n }\n .text-gray-700 {\n color: var(--color-gray-700);\n }\n .text-gray-900 {\n color: var(--color-gray-900);\n }\n .text-green-500 {\n color: var(--color-green-500);\n }\n .text-white {\n color: var(--color-white);\n }\n .opacity-50 {\n opacity: 50%;\n }\n .shadow-lg {\n --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .shadow-md {\n --tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .shadow-xl {\n --tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 8px 10px -6px var(--tw-shadow-color, rgb(0 0 0 / 0.1));\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n .backdrop-blur-md {\n --tw-backdrop-blur: blur(var(--blur-md));\n -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n }\n .backdrop-blur-sm {\n --tw-backdrop-blur: blur(var(--blur-sm));\n -webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);\n }\n .transition {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-all {\n transition-property: all;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-colors {\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .transition-opacity {\n transition-property: opacity;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n }\n .duration-200 {\n --tw-duration: 200ms;\n transition-duration: 200ms;\n }\n .ease-in-out {\n --tw-ease: var(--ease-in-out);\n transition-timing-function: var(--ease-in-out);\n }\n .hover\\:bg-gray-200 {\n &:hover {\n @media (hover: hover) {\n background-color: var(--color-gray-200);\n }\n }\n }\n .hover\\:bg-gray-300 {\n &:hover {\n @media (hover: hover) {\n background-color: var(--color-gray-300);\n }\n }\n }\n .hover\\:bg-white\\/90 {\n &:hover {\n @media (hover: hover) {\n background-color: color-mix(in srgb, #fff 90%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 90%, transparent);\n }\n }\n }\n }\n .hover\\:text-gray-200 {\n &:hover {\n @media (hover: hover) {\n color: var(--color-gray-200);\n }\n }\n }\n .focus\\:ring-2 {\n &:focus {\n --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);\n box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);\n }\n }\n .focus\\:ring-gray-400 {\n &:focus {\n --tw-ring-color: var(--color-gray-400);\n }\n }\n .focus\\:ring-offset-1 {\n &:focus {\n --tw-ring-offset-width: 1px;\n --tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);\n }\n }\n .focus\\:outline-none {\n &:focus {\n --tw-outline-style: none;\n outline-style: none;\n }\n }\n .disabled\\:cursor-not-allowed {\n &:disabled {\n cursor: not-allowed;\n }\n }\n .disabled\\:bg-white\\/50 {\n &:disabled {\n background-color: color-mix(in srgb, #fff 50%, transparent);\n @supports (color: color-mix(in lab, red, red)) {\n background-color: color-mix(in oklab, var(--color-white) 50%, transparent);\n }\n }\n }\n .disabled\\:opacity-50 {\n &:disabled {\n opacity: 50%;\n }\n }\n .lg\\:h-32 {\n @media (width >= 64rem) {\n height: calc(var(--spacing) * 32);\n }\n }\n .lg\\:w-32 {\n @media (width >= 64rem) {\n width: calc(var(--spacing) * 32);\n }\n }\n .lg\\:px-10 {\n @media (width >= 64rem) {\n padding-inline: calc(var(--spacing) * 10);\n }\n }\n .lg\\:pb-12 {\n @media (width >= 64rem) {\n padding-bottom: calc(var(--spacing) * 12);\n }\n }\n .lg\\:text-2xl {\n @media (width >= 64rem) {\n font-size: var(--text-2xl);\n line-height: var(--tw-leading, var(--text-2xl--line-height));\n }\n }\n .lg\\:text-3xl {\n @media (width >= 64rem) {\n font-size: var(--text-3xl);\n line-height: var(--tw-leading, var(--text-3xl--line-height));\n }\n }\n .lg\\:text-4xl {\n @media (width >= 64rem) {\n font-size: var(--text-4xl);\n line-height: var(--tw-leading, var(--text-4xl--line-height));\n }\n }\n .lg\\:text-lg {\n @media (width >= 64rem) {\n font-size: var(--text-lg);\n line-height: var(--tw-leading, var(--text-lg--line-height));\n }\n }\n .\\[\\&\\:\\:cue\\]\\:absolute {\n &::cue {\n position: absolute;\n }\n }\n .\\[\\&\\:\\:cue\\]\\:top-\\[6\\%\\] {\n &::cue {\n top: 6%;\n }\n }\n .\\[\\&\\:\\:cue\\]\\:rounded-md {\n &::cue {\n border-radius: var(--radius-md);\n }\n }\n .\\[\\&\\:\\:cue\\]\\:bg-gray-50 {\n &::cue {\n background-color: var(--color-gray-50);\n }\n }\n .\\[\\&\\:\\:cue\\]\\:px-2 {\n &::cue {\n padding-inline: calc(var(--spacing) * 2);\n }\n }\n .\\[\\&\\:\\:cue\\]\\:py-1 {\n &::cue {\n padding-block: calc(var(--spacing) * 1);\n }\n }\n .\\[\\&\\:\\:cue\\]\\:text-xl {\n &::cue {\n font-size: var(--text-xl);\n line-height: var(--tw-leading, var(--text-xl--line-height));\n }\n }\n .\\[\\&\\:\\:cue\\]\\:text-\\[\\#1E1E1E\\] {\n &::cue {\n color: #1E1E1E;\n }\n }\n}\n.noCursor {\n cursor: none !important;\n}\n.icon-class {\n height: calc(var(--spacing) * 14);\n width: calc(var(--spacing) * 14);\n cursor: pointer;\n color: var(--color-gray-400);\n transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to;\n transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));\n transition-duration: var(--tw-duration, var(--default-transition-duration));\n --tw-duration: 200ms;\n transition-duration: 200ms;\n &:hover {\n @media (hover: hover) {\n color: var(--color-gray-200);\n }\n }\n @media (width >= 64rem) {\n height: calc(var(--spacing) * 18);\n }\n @media (width >= 64rem) {\n width: calc(var(--spacing) * 18);\n }\n}\n@property --tw-translate-x {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-translate-y {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-translate-z {\n syntax: \"*\";\n inherits: false;\n initial-value: 0;\n}\n@property --tw-rotate-x {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-rotate-y {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-rotate-z {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-skew-x {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-skew-y {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-border-style {\n syntax: \"*\";\n inherits: false;\n initial-value: solid;\n}\n@property --tw-gradient-position {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-gradient-from {\n syntax: \"<color>\";\n inherits: false;\n initial-value: #0000;\n}\n@property --tw-gradient-via {\n syntax: \"<color>\";\n inherits: false;\n initial-value: #0000;\n}\n@property --tw-gradient-to {\n syntax: \"<color>\";\n inherits: false;\n initial-value: #0000;\n}\n@property --tw-gradient-stops {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-gradient-via-stops {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-gradient-from-position {\n syntax: \"<length-percentage>\";\n inherits: false;\n initial-value: 0%;\n}\n@property --tw-gradient-via-position {\n syntax: \"<length-percentage>\";\n inherits: false;\n initial-value: 50%;\n}\n@property --tw-gradient-to-position {\n syntax: \"<length-percentage>\";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-font-weight {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-shadow-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-shadow-alpha {\n syntax: \"<percentage>\";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-inset-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-shadow-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-inset-shadow-alpha {\n syntax: \"<percentage>\";\n inherits: false;\n initial-value: 100%;\n}\n@property --tw-ring-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-ring-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-inset-ring-color {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-inset-ring-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-ring-inset {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-ring-offset-width {\n syntax: \"<length>\";\n inherits: false;\n initial-value: 0px;\n}\n@property --tw-ring-offset-color {\n syntax: \"*\";\n inherits: false;\n initial-value: #fff;\n}\n@property --tw-ring-offset-shadow {\n syntax: \"*\";\n inherits: false;\n initial-value: 0 0 #0000;\n}\n@property --tw-backdrop-blur {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-brightness {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-contrast {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-grayscale {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-hue-rotate {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-invert {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-opacity {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-saturate {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-backdrop-sepia {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-duration {\n syntax: \"*\";\n inherits: false;\n}\n@property --tw-ease {\n syntax: \"*\";\n inherits: false;\n}\n@keyframes spin {\n to {\n transform: rotate(360deg);\n }\n}\n@layer properties {\n @supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {\n *, ::before, ::after, ::backdrop {\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-translate-z: 0;\n --tw-rotate-x: initial;\n --tw-rotate-y: initial;\n --tw-rotate-z: initial;\n --tw-skew-x: initial;\n --tw-skew-y: initial;\n --tw-border-style: solid;\n --tw-gradient-position: initial;\n --tw-gradient-from: #0000;\n --tw-gradient-via: #0000;\n --tw-gradient-to: #0000;\n --tw-gradient-stops: initial;\n --tw-gradient-via-stops: initial;\n --tw-gradient-from-position: 0%;\n --tw-gradient-via-position: 50%;\n --tw-gradient-to-position: 100%;\n --tw-font-weight: initial;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-color: initial;\n --tw-shadow-alpha: 100%;\n --tw-inset-shadow: 0 0 #0000;\n --tw-inset-shadow-color: initial;\n --tw-inset-shadow-alpha: 100%;\n --tw-ring-color: initial;\n --tw-ring-shadow: 0 0 #0000;\n --tw-inset-ring-color: initial;\n --tw-inset-ring-shadow: 0 0 #0000;\n --tw-ring-inset: initial;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-backdrop-blur: initial;\n --tw-backdrop-brightness: initial;\n --tw-backdrop-contrast: initial;\n --tw-backdrop-grayscale: initial;\n --tw-backdrop-hue-rotate: initial;\n --tw-backdrop-invert: initial;\n --tw-backdrop-opacity: initial;\n --tw-backdrop-saturate: initial;\n --tw-backdrop-sepia: initial;\n --tw-duration: initial;\n --tw-ease: initial;\n }\n }\n}\r\n";
styleInject(css_248z$2,{"insertAt":"top"});
const useVideoStore = create((set) => ({
videoRef: null,
setVideoRef: (ref) => set({ videoRef: ref }),
videoWrapperRef: null,
setVideoWrapperRef: (ref) => set({ videoWrapperRef: ref }),
playing: false,
setPlaying: (playing) => set({ playing }),
isBuffering: false,
setIsBuffering: (isBuffering) => set({ isBuffering }),
isPlaying: false,
setIsPlaying: (isPlaying) => set({ isPlaying }),
muted: false,
setMuted: (muted) => set({ muted }),
volume: 1,
setVolume: (volume) => set({ volume }),
controls: false,
setControls: (controls) => set({ controls }),
currentTime: 0,
setCurrentTime: (currentTime) => set({ currentTime }),
duration: 0,
setDuration: (duration) => set({ duration }),
isFullscreen: false,
setIsFullscreen: (isFullscreen) => set({ isFullscreen }),
hlsInstance: undefined,
setHlsInstance: (hlsInstance) => set({ hlsInstance }),
qualityLevels: undefined,
setQualityLevels: (qualityLevels) => set({ qualityLevels }),
activeQuality: "auto",
setActiveQuality: (activeQuality) => set({ activeQuality }),
activeSubtitle: null,
setActiveSubtitle: (subtitle) => set({ activeSubtitle: subtitle }),
subtitles: [],
setSubtitles: (subtitles) => set({ subtitles }),
showIntroSkip: false,
setShowIntroSkip: (show) => set({ showIntroSkip: show }),
autoPlayNext: false,
setAutoPlayNext: (value) => set({ autoPlayNext: value }),
// Next Episode
episodeList: [],
setEpisodeList: (list) => set({ episodeList: list }),
currentEpisodeIndex: 0,
setCurrentEpisodeIndex: (index) => set({ currentEpisodeIndex: index }),
showCountdown: false,
setShowCountdown: (show) => set({ showCountdown: show }),
countdownTime: 10,
setCountdownTime: (time) => set({ countdownTime: time }),
}));
/**
* @description Converts seconds to hh:mm:ss
* @param seconds
* @returns
*/
const timeFormat = (seconds) => {
if (isNaN(seconds)) {
return `00:00`;
}
const date = new Date(seconds * 1000);
const hh = date.getUTCHours();
const mm = date.getUTCMinutes();
const ss = date.getUTCSeconds().toString().padStart(2, "0");
if (hh) {
return `${hh}:${mm.toString().padStart(2, "0")}:${ss}`;
}
return `${mm}:${ss}`;
};
/**
* @description Converts seconds to milliseconds
* @param seconds
* @returns
*/
const secondsToMilliseconds = (seconds) => {
return seconds * 1000;
};
/**
* @description get extension from url
* @param url
* @returns string | undefined
*/
const getExtensionFromUrl = (url) => {
const extension = url?.split(".")?.pop();
if (extension === "m3u8") {
return "hls";
}
return extension;
};
function getPositionPercent(max, current) {
const divider = max || -1; // prevent division by zero
return (current * 100) / divider;
}
const isInRange = (time, start, end) => time >= start && time <= end;
function getTimeScale(currentTime, startTime, endTime, isTimePassed) {
const isActiveTime = isInRange(currentTime, startTime, endTime);
const timeDiff = endTime - startTime;
const timeDiffWithCurrent = currentTime - startTime;
const currentScalePercent = isActiveTime ? timeDiffWithCurrent / timeDiff : 0;
return isTimePassed ? 1 : currentScalePercent;
}
const TimeCodeItem = memo(({ label = "", startTime, maxTime, endTime, currentTime, seekHoverTime, bufferTime, isTimePassed = false, isBufferPassed = false, isHoverPassed = false, onHover = () => undefined, withGap, trackColor, }) => {
const positionPercent = getPositionPercent(maxTime, startTime);
const timeDiff = endTime - startTime;
const widthPercent = (timeDiff / maxTime) * 100;
const mainClassName = `main${withGap ? " with-gap" : ""}`;
const currentTimeScale = getTimeScale(currentTime, startTime, endTime, isTimePassed);
const seekHoverTimeScale = getTimeScale(seekHoverTime, startTime, endTime, isHoverPassed);
const bufferTimeScale = getTimeScale(bufferTime, startTime, endTime, isBufferPassed);
const handleMouseMove = () => onHover(label);
return (React__default.createElement("div", { className: mainClassName, onMouseMove: handleMouseMove, style: {
width: `${widthPercent}%`,
left: `${positionPercent}%`,
} },
React__default.createElement("div", { className: "inner-seek-block buffered", "data-test-id": "test-buffered", style: { transform: `scaleX(${bufferTimeScale})` } }),
React__default.createElement("div", { className: "inner-seek-block seek-hover", "data-test-id": "test-seek-hover", style: { transform: `scaleX(${seekHoverTimeScale})` } }),
React__default.createElement("div", { className: "inner-seek-block connect", style: {
transform: `scaleX(${currentTimeScale})`,
backgroundColor: trackColor || "#ff0000",
} })));
});
function positionToMs(max, position, trackWidth) {
const percent = (position * 100) / trackWidth;
return Math.floor(+(percent * (max / 100)));
}
const getEndTimeByIndex = (timeCodes, index, max) => (index + 1 < timeCodes.length ? timeCodes[index + 1].fromMs : max);
const TimeCodes = ({ max = 1000, currentTime = 0, bufferTime = 0, seekHoverPosition = 0, timeCodes, trackWidth, mobileSeeking, label, setLabel, trackColor, }) => {
const hoverTimeValue = positionToMs(max, seekHoverPosition, trackWidth);
const handleLabelChange = useCallback((currentLabel) => {
if (label !== currentLabel) {
setLabel(currentLabel);
}
}, [label]);
useEffect(() => {
if (!mobileSeeking) {
return;
}
const currentCode = timeCodes?.find(({ fromMs }, index) => {
const endTime = getEndTimeByIndex(timeCodes, index, max);
return isInRange(currentTime, fromMs, endTime);
});
if (currentCode?.description !== label) {
setLabel(currentCode?.description || "");
}
}, [currentTime, label, max, timeCodes]);
return (React__default.createElement(React__default.Fragment, null, timeCodes?.map(({ fromMs, description }, index) => {
const endTime = getEndTimeByIndex(timeCodes, index, max);
const isTimePassed = endTime <= currentTime;
const isBufferPassed = endTime <= bufferTime;
const isHoverPassed = endTime <= hoverTimeValue;
let inRange = isInRange(currentTime, fromMs, endTime);
const newCurrentTime = isTimePassed || !inRange ? 0 : currentTime;
inRange = isInRange(bufferTime, fromMs, endTime);
const newBufferTime = isBufferPassed || !inRange ? 0 : bufferTime;
inRange = isInRange(hoverTimeValue, fromMs, endTime);
const newHoverTime = isHoverPassed || !inRange ? 0 : hoverTimeValue;
return (React__default.createElement(TimeCodeItem, { key: fromMs, label: description, maxTime: max, startTime: fromMs, endTime: endTime, isTimePassed: isTimePassed, isBufferPassed: isBufferPassed, isHoverPassed: isHoverPassed, currentTime: newCurrentTime, bufferTime: newBufferTime, seekHoverTime: newHoverTime, onHover: handleLabelChange, withGap: true, trackColor: trackColor }));
})));
};
function getHoverTimePosition(seekHoverPosition, hoverTimeElement, trackWidth, limitTimeTooltipBySides) {
let position = 0;
if (hoverTimeElement) {
position = seekHoverPosition - hoverTimeElement.offsetWidth / 2;
if (limitTimeTooltipBySides) {
if (position < 0) {
position = 0;
}
else if (position + hoverTimeElement.offsetWidth > trackWidth) {
position = trackWidth - hoverTimeElement.offsetWidth;
}
}
}
return { transform: `translateX(${position}px)` };
}
function millisecondsToTime(ms, offset = 0) {
const roundedSeconds = Math.round(ms / 1000 + offset);
const hours = Math.floor(roundedSeconds / 3600);
const divirsForMinutes = roundedSeconds % 3600;
const minutes = Math.floor(divirsForMinutes / 60);
const sec = Math.ceil(divirsForMinutes % 60);
return {
hh: hours.toString(),
mm: minutes < 10 ? `0${minutes}` : minutes.toString(),
ss: sec < 10 ? `0${sec}` : sec.toString(),
};
}
function timeToTimeString(max, seekHoverTime, offset = 0, minutesPrefix = "", secondsPrefix = "") {
const times = millisecondsToTime(seekHoverTime, offset);
if (max + offset < 60 * 1000) {
return secondsPrefix + times.ss;
}
if (max + offset < 3600 * 1000) {
return `${minutesPrefix + times.mm}:${times.ss}`;
}
return `${times.hh}:${times.mm}:${times.ss}`;
}
const HoverTimeWithPreview = ({ max, hoverTimeValue, offset, trackWidth, seekHoverPosition, isThumbActive, limitTimeTooltipBySides, label, minutesPrefix, secondsPrefix, getPreviewScreenUrl, }) => {
const hoverTimeElement = useRef(null);
const hoverTimeClassName = isThumbActive ? "hover-time active" : "hover-time";
const hoverTimePosition = getHoverTimePosition(seekHoverPosition, hoverTimeElement?.current, trackWidth, limitTimeTooltipBySides);
const hoverTimeString = timeToTimeString(max, hoverTimeValue, offset, minutesPrefix, secondsPrefix);
return (React__default.createElement("div", { className: hoverTimeClassName, style: hoverTimePosition, ref: hoverTimeElement, "data-testid": "hover-time" },
isThumbActive && getPreviewScreenUrl && (React__default.createElement("div", { className: "preview-screen", style: {
backgroundImage: `url(${getPreviewScreenUrl(hoverTimeValue)})`,
} })),
label && React__default.createElement("div", null, label),
hoverTimeString));
};
const Thumb = ({ max, currentTime, isThumbActive, trackColor, }) => {
const getThumbHandlerPosition = () => {
const thumbConstantOffset = -6;
const leftPosition = (currentTime / max) * 100;
return {
left: `calc(${leftPosition}% + ${thumbConstantOffset}px)`,
};
};
return (React__default.createElement("div", { className: isThumbActive ? "thumb active" : "thumb active", "data-testid": "testThumb", style: getThumbHandlerPosition() },
React__default.createElement("div", { className: "handler", style: {
backgroundColor: trackColor || "#ff0000",
} })));
};
const VideoSeekSlider = ({ max = 1000, currentTime = 0, bufferTime = 0, hideThumbTooltip = false, offset = 0, secondsPrefix = "", minutesPrefix = "", limitTimeTooltipBySides = true, timeCodes, onChange = () => undefined, getPreviewScreenUrl, trackColor, }) => {
const [seekHoverPosition, setSeekHoverPosition] = useState(0);
const [label, setLabel] = useState("");
const seeking = useRef(false);
const mobileSeeking = useRef(false);
const trackElement = useRef(null);
const trackWidth = trackElement.current?.offsetWidth || 0;
const isThumbActive = seekHoverPosition > 0 || seeking.current;
const hoverTimeValue = positionToMs(max, seekHoverPosition, trackWidth);
const changeCurrentTimePosition = (pageX) => {
const clientRect = trackElement.current?.getBoundingClientRect();
const left = clientRect?.left || 0;
const width = clientRect?.width || 0;
let position = pageX - left;
position = position < 0 ? 0 : position;
position = position > width ? width : position;
const percent = (position * 100) / width;
const time = +(percent * (max / 100)).toFixed(0);
setSeekHoverPosition(position);
onChange(time, time + offset);
};
const handleTouchSeeking = (event) => {
event.preventDefault();
event.stopPropagation();
if (!mobileSeeking.current) {
return;
}
const { changedTouches } = event;
let pageX = changedTouches?.[changedTouches.length - 1]?.pageX || 0;
pageX = pageX < 0 ? 0 : pageX;
changeCurrentTimePosition(pageX);
};
const handleSeeking = (event) => {
if (seeking.current) {
changeCurrentTimePosition(event.pageX);
}
};
const handleTrackHover = (clear, event) => {
const left = trackElement.current?.getBoundingClientRect().left || 0;
const position = clear ? 0 : event.pageX - left;
setSeekHoverPosition(position);
};
const setMobileSeeking = (state = true) => {
mobileSeeking.current = state;
setSeekHoverPosition(state ? seekHoverPosition : 0);
};
const setSeeking = (state, event) => {
event.preventDefault();
handleSeeking(event);
seeking.current = state;
setSeekHoverPosition(state ? seekHoverPosition : 0);
};
const mouseSeekingHandler = (event) => {
setSeeking(false, event);
};
const mobileTouchSeekingHandler = () => {
setMobileSeeking(false);
};
useEffect(() => {
if (!mobileSeeking.current) {
return;
}
const currentCode = timeCodes?.find(({ fromMs }, index) => {
const endTime = getEndTimeByIndex(timeCodes, index, max);
return isInRange(currentTime, fromMs, endTime);
});
if (currentCode?.description !== label) {
setLabel(currentCode?.description || "");
}
}, [currentTime, label, max, timeCodes]);
useEffect(() => {
window.addEventListener("mousemove", handleSeeking);
window.addEventListener("mouseup", mouseSeekingHandler);
window.addEventListener("touchmove", handleTouchSeeking);
window.addEventListener("touchend", mobileTouchSeekingHandler);
return () => {
window.removeEventListener("mousemove", handleSeeking);
window.removeEventListener("mouseup", mouseSeekingHandler);
window.removeEventListener("touchmove", handleTouchSeeking);
window.removeEventListener("touchend", mobileTouchSeekingHandler);
};
}, [max, offset, trackWidth]);
return (React__default.createElement("div", { className: "ui-video-seek-slider" },
React__default.createElement("div", { className: isThumbActive ? "track active" : "track", ref: trackElement, onMouseMove: (event) => handleTrackHover(false, event), onMouseLeave: (event) => handleTrackHover(true, event), onMouseDown: (event) => setSeeking(true, event), onTouchStart: () => setMobileSeeking(true), "data-testid": "main-track" },
Boolean(timeCodes?.length) && (React__default.createElement(TimeCodes, { currentTime: currentTime, max: max, bufferTime: bufferTime, seekHoverPosition: seekHoverPosition, timeCodes: timeCodes, mobileSeeking: mobileSeeking.current, trackWidth: trackWidth, label: label, setLabel: setLabel, trackColor: trackColor })),
!timeCodes && (React__default.createElement(TimeCodeItem, { maxTime: max, startTime: 0, endTime: max, currentTime: currentTime, bufferTime: bufferTime, seekHoverTime: hoverTimeValue, trackColor: trackColor }))),
!hideThumbTooltip && (React__default.createElement(HoverTimeWithPreview, { max: max, hoverTimeValue: hoverTimeValue, isThumbActive: isThumbActive, label: label, limitTimeTooltipBySides: limitTimeTooltipBySides, offset: offset, seekHoverPosition: seekHoverPosition, trackWidth: trackWidth, getPreviewScreenUrl: getPreviewScreenUrl, minutesPrefix: minutesPrefix, secondsPrefix: secondsPrefix })),
React__default.createElement(Thumb, { max: max, currentTime: currentTime, isThumbActive: isThumbActive, trackColor: trackColor })));
};
var css_248z$1 = ".ui-video-seek-slider {\r\n position: relative;\r\n touch-action: none;\r\n}\r\n.ui-video-seek-slider:focus {\r\n outline: none;\r\n}\r\n.ui-video-seek-slider .track {\r\n padding: 0;\r\n cursor: pointer;\r\n outline: none;\r\n}\r\n.ui-video-seek-slider .track:focus {\r\n border: 0;\r\n outline: none;\r\n}\r\n.ui-video-seek-slider .track .main {\r\n width: 100%;\r\n outline: none;\r\n height: 18px;\r\n top: 0;\r\n position: absolute;\r\n display: flex;\r\n align-items: center;\r\n box-sizing: border-box;\r\n}\r\n.ui-video-seek-slider .track .main:before {\r\n content: \"\";\r\n position: absolute;\r\n width: 100%;\r\n height: 3px;\r\n background-color: rgba(255, 255, 255, 0.2);\r\n overflow: hidden;\r\n transition: height 0.1s;\r\n outline: none;\r\n}\r\n.ui-video-seek-slider .track .main .inner-seek-block {\r\n position: absolute;\r\n width: 100%;\r\n height: 3px;\r\n transition: height 0.1s, opacity 0.4s;\r\n transform-origin: 0 0;\r\n}\r\n.ui-video-seek-slider .track .main:focus {\r\n border: 0;\r\n outline: none;\r\n}\r\n.ui-video-seek-slider .track .main .buffered {\r\n background-color: rgba(255, 255, 255, 0.3);\r\n z-index: 2;\r\n}\r\n.ui-video-seek-slider .track .main .seek-hover {\r\n background-color: rgba(255, 255, 255, 0.5);\r\n z-index: 1;\r\n}\r\n.ui-video-seek-slider .track .main .connect {\r\n background-color: #ff0000;\r\n z-index: 3;\r\n transform-origin: 0 0;\r\n}\r\n.ui-video-seek-slider .track .main.with-gap .inner-seek-block,\r\n.ui-video-seek-slider .track .main.with-gap:before {\r\n width: calc(100% - 2px);\r\n margin: 0 auto;\r\n}\r\n@media (hover) {\r\n .ui-video-seek-slider .track .main:hover:before {\r\n height: 8px;\r\n }\r\n .ui-video-seek-slider .track .main:hover .inner-seek-block {\r\n height: 8px;\r\n }\r\n}\r\n.ui-video-seek-slider .thumb {\r\n pointer-events: none;\r\n position: absolute;\r\n width: 12px;\r\n height: 12px;\r\n left: -6px;\r\n z-index: 4;\r\n top: 3px;\r\n}\r\n.ui-video-seek-slider .thumb .handler {\r\n border-radius: 100%;\r\n width: 100%;\r\n height: 100%;\r\n background-color: #ff0000;\r\n opacity: 0;\r\n transform: scale(0.4);\r\n transition: transform 0.2s, opacity 0.2s;\r\n}\r\n.ui-video-seek-slider .thumb.active .handler {\r\n opacity: 1;\r\n transform: scale(1);\r\n}\r\n.ui-video-seek-slider .hover-time {\r\n text-shadow: 1px 1px 1px #000;\r\n position: absolute;\r\n line-height: 18px;\r\n font-size: 16px;\r\n color: #ddd;\r\n bottom: 5px;\r\n left: 0;\r\n padding: 5px 10px;\r\n opacity: 0;\r\n pointer-events: none;\r\n text-align: center;\r\n}\r\n.ui-video-seek-slider .hover-time.active {\r\n opacity: 1;\r\n}\r\n.ui-video-seek-slider .hover-time .preview-screen {\r\n background-repeat: no-repeat;\r\n background-size: cover;\r\n background-position: center;\r\n width: 200px;\r\n height: 110px;\r\n border-radius: 5px;\r\n background-color: #000;\r\n margin: 0 auto 10px;\r\n}\r\n.ui-video-seek-slider:hover .track .main .seek-hover {\r\n opacity: 1;\r\n}\r\n";
styleInject(css_248z$1,{"insertAt":"top"});
const BottomControls = ({ config }) => {
const { videoRef, currentTime, isFullscreen } = useVideoStore();
const duration = videoRef?.duration;
return (React__default.createElement("div", { className: "px-10" },
React__default.createElement(VideoSeekSlider, { max: secondsToMilliseconds(duration || 0), currentTime: secondsToMilliseconds(currentTime || 0), bufferTime: secondsToMilliseconds(0), onChange: (currentTime) => {
if (videoRef) {
videoRef.currentTime = currentTime / 1000;
}
}, secondsPrefix: "00:00:", minutesPrefix: "00:", getPreviewScreenUrl: config?.seekBarConfig?.getPreviewScreenUrl, timeCodes: config?.seekBarConfig?.timeCodes, trackColor: config?.seekBarConfig?.trackColor }),
React__default.createElement("div", { className: `pt-6 ${isFullscreen ? "pb-10" : "pb-16"} lg:pb-12 flex items-center gap-4 text-white` },
React__default.createElement("span", { className: "text-lg lg:text-2xl font-semibold text-white cursor-pointer hover:text-gray-200 transition-colors duration-200" }, timeFormat(currentTime || 0)),
React__default.createElement("span", { className: "text-lg lg:text-3xl font-semibold text-gray-500 cursor-pointer hover:text-gray-200 transition-colors duration-200" }, "/"),
React__default.createElement("span", { className: "text-lg lg:text-2xl font-semibold text-gray-400 cursor-pointer hover:text-gray-200 transition-colors duration-200" }, timeFormat(duration || 0)))));
};
const Tooltip = ({ children, title, position = "top", }) => {
const [visible, setVisible] = useState(false);
const positionStyles = {
top: "bottom-full left-1/2 transform -translate-x-1/2 mb-2",
bottom: "top-full left-1/2 transform -translate-x-1/2 mt-2",
left: "right-full top-1/2 transform -translate-y-1/2 mr-2",
right: "left-full top-1/2 transform -translate-y-1/2 ml-2",
};
return (React__default.createElement("div", { className: "relative inline-block cursor-pointer", onMouseEnter: () => setVisible(true), onMouseLeave: () => setVisible(false) },
children,
visible && (React__default.createElement("div", { className: `absolute z-50 px-3 py-1 text-sm text-white bg-gray-900 rounded-md shadow-md transition-opacity duration-200 ease-in-out ${positionStyles[position]}` }, title))));
};
const Popover = ({ button, children, closeOnButtonClick = false, }) => {
const [isOpen, setIsOpen] = useState(false);
const popoverRef = useRef(null);
const buttonRef = useRef(null);
// Close on outside click or Escape key
useEffect(() => {
const handleClickOutside = (event) => {
if (popoverRef.current &&
!popoverRef.current.contains(event.target) &&
buttonRef.current &&
!buttonRef.current.contains(event.target)) {
setIsOpen(false);
}
};
cons